#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int n;
struct Node {
double x, y;
}p[N], stk[N];
bool Andrew_cmp(Node a, Node b) {
return a.x != b.x ? a.x < b.x : a.y < b.y;
}
double dis(Node a, Node b) {
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
bool Graham_cmp(Node a, Node b) {
double x0 = p[1].x, y0 = p[1].y;
double det = (a.x - x0) * (b.y - y0) - (a.y - y0) * (b.x - x0);
if (det != 0) return det > 0;
return dis(a, p[1]) < dis(b, p[1]);
}
double cross(Node a, Node b, Node c) {
return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
}
double Andrew() {
sort(p + 1, p + n + 1, Andrew_cmp);
int top = 0;
for (int i = 1; i <= n; i ++) {
while (top > 1 && cross(stk[top - 1], stk[top], p[i]) <= 0) top --;
stk[++ top] = p[i];
}
int t = top;
for (int i = n - 1; i >= 1; i --) {
while (top > t && cross(stk[top - 1], stk[top], p[i]) <= 0) top --;
stk[++ top] = p[i];
}
double res = 0;
for (int i = 1; i < top; i ++) res += dis(stk[i], stk[i + 1]);
return res;
}
double Graham() {
int idx = 1;
for (int i = 1; i <= n; i ++) {
if (p[i].y < p[idx].y) idx = i;
else if (p[i].y == p[idx].y && p[i].x < p[idx].x) idx = i;
}
swap(p[idx], p[1]);
sort(p + 2, p + n + 1, Graham_cmp);
p[n + 1] = p[1];
int top = 0;
for (int i = 1; i <= n + 1; i ++) {
while (top > 1 && cross(stk[top - 1], stk[top], p[i]) < 0) top --;
stk[++ top] = p[i];
}
double res = 0;
for (int i = 1; i < top; i ++) res += dis(stk[i], stk[i + 1]);
return res;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i ++) cin >> p[i].x >> p[i].y;
printf("%.2lf\n", Andrew());
printf("%.2lf\n", Graham());
}