#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
struct Point {
double x, y;
Point friend operator - (Point a, Point b) {
return {a.x - b.x, a.y - b.y};
}
}p[105], Stack[105];
double X(Point a, Point b) {
return a.x * b.y - a.y * b.x;
}
double multi(Point p1, Point p2, Point p3) {
return X(p2 - p1, p3 - p1);
}
double dis(Point a, Point b) {
Point c = a - b;
return sqrt(c.x * c.x + c.y * c.y);
}
// 极角排序
int cmp(Point a, Point b) {
double x = X(a - p[1], b - p[1]);
if(x > 0) return 1;
if(x == 0 && dis(a, p[1]) < dis(b, p[1])) return 1;
return 0;
}
int main()
{
int N;
while(scanf("%d", &N) && N)
{
for(int i = 1; i <= N; i++)
scanf("%lf %lf", &p[i].x, &p[i].y);
// N 等于 1 和 2 特殊判断
if(N == 1){
printf("0.00\n");
continue;
}
else if(N == 2){
printf("%.2f\n", dis(p[1], p[2]));
continue;
}
// 先选出点集中y坐标最小的点,如果y坐标相同则相同点中x坐标最小的点
int k = 1;
for(int i = 2; i <= N; i++)
if(p[i].y < p[k].y || (p[i].y == p[k].y && p[i].x < p[k].x))
k = i;
swap(p[1], p[k]);
// 按极角排序
sort(p + 2, p + N + 1, cmp);
Stack[1] = p[1];
Stack[2] = p[2];
int tot = 2;
for(int i = 3; i <= N; i++) {
// 发现在栈里边一个顶点处没有向左转时,就把该顶点移除出去
while(tot >= 2 && multi(Stack[tot - 1], Stack[tot], p[i]) <= 0) tot--;
Stack[++tot] = p[i];
}
// 便于下边计算
Stack[tot + 1] = Stack[1];
double sum = 0;
for(int i = 1; i <= tot; i++) {
sum += dis(Stack[i], Stack[i + 1]);
}
printf("%.2f\n", sum);
}
return 0;
}