Problem:
Spiral Footrace
Let us enjoy extraordinary footraces at an athletic field.
Before starting the race, small flags representing checkpoints are set up
at random on the field. Every runner has to pass all the checkpoints one by
one in the spiral order specified below.
The starting point is the southwest corner of the athletic field.
At the starting point, runners are facing north.
During the race, they run clockwise in a spiral passing
every checkpoint as illustrated in the following figure.
When moving from one flag to the next, they take a straight path.
This means that the course of a race is always piecewise linear.
Upon arriving at some flag, a runner has to determine the next flag
among those that are not yet visited.
That flag shall be the one at the smallest angle to the right of the direction
that the runner is facing. When more than two flags are on the same straight
line, the runner visits the nearest flag first.
The goal position is the place of the last visited flag.
Your job is to write a program that calculates the length of the course from
the starting point to the goal, supposing that the course consists of
line segments connected by flags.
The position of each flag is given by a coordinate pair
(
x
i
,
y
i
), which is limited
to the first quadrant. The starting point is fixed to the origin (0, 0) where a
flag is always set up.
Input
The input contains multiple data sets, each representing a collection of
flag positions for a footrace.  A data set is given in the following
format.
n
x
1
y
1
x
2
y
2
...
x
n
y
n
Here,
n
is the number of flag positions (1 <=
n
<= 400).
The position of the
i
-th flag is given by
(
x
i
,
y
i
), where
x
i
and
y
i
are integers
in meter between 0 and 500 inclusive. 
There may be white spaces (blanks and/or tabs) before, in between, or after
x
i
and
y
i
.
Once a certain
coordinate pair (
x
i
,
y
i
) is given,
the same one will not appear later in the data set, and the origin (0, 0)
will not appear either.
A data set beginning with
n
= 0 indicates end of the input.
Output
For each data set, your program should output the length of the running course
in meter. Each length should appear on a separate line, with
one digit to the right of the decimal point, after rounding it to one
decimal place.
Sample Input
8
   60  70
   20  40
   50  50
   70  10
   10  70
   80  90
   70  50
  100  50
5
   60  50
    0  80
   60  20
   10  20
   60  80
0
Output for the Sample Input
388.9
250.0

Submitted solutions:

code_snippet: /*
#include<iostream>
#include<cstdio>
#include<cmath>
#include<sstream>
#include<algorithm>
#include<cassert>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define F first
#define S second
#define all(n) (n).begin(),(n).end()
#define EPS (1e-8)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a,b) (fabs((a)-(b)) < EPS)
using namespace std;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<vi> vvi;
struct Point
{
  double x,y;
  int index;
  Point(double x=-inf,double y=-inf):x(x),y(y){}
 
  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double p){return Point(x*p,y*p);}
 
  bool operator < (const Point& p)const
  {
    return !equals(x,p.x)?x < p.x:y > p.y;
  }
  bool operator == (const Point &p)const
  {
    return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
  }
};
 
struct Segment
{
  Point p1,p2;
  Segment(Point p1=Point(-inf,-inf),Point p2=Point(-inf,-inf)):p1(p1),p2(p2){}
};
 
typedef vector<Point> Polygon;
typedef Segment Line;
typedef vector<Point> Polygon;
 
double dot(Point a,Point b)
{
  return a.x*b.x+a.y*b.y;
}
 
double cross(Point a,Point b)
{
  return a.x*b.y-a.y*b.x;
}
 
double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}
 
double toRad(double agl)
{
  return agl*M_PI/180.0;
}
 
int ccw(Point p0,Point p1,Point p2)
{
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) <-EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS) return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}
 
 
bool PointEquals(Point a,Point b)
{
  return equals(a.x,b.x) && equals(a.y,b.y);
}
 
double abs(Point a)
{
  return sqrt(norm(a));
}
 
double getDistanceLP(Line s,Point p)
{
  return abs(cross(s.p2-s.p1,p-s.p1))/abs(s.p2-s.p1);
}
 
double getDistanceSP(Segment s,Point p)
{
  if(dot(s.p2-s.p1,p-s.p1) < 0.0)return abs(p-s.p1);
  if(dot(s.p1-s.p2,p-s.p2) < 0.0)return abs(p-s.p2);
  return getDistanceLP(s,p);
}
 
Polygon andrewScan(Polygon s,Point now)
{
  Polygon u,l;
  if(s.size() < 3)return s;
  sort(all(s));
 
  u.push_back(s[0]);
  u.push_back(s[1]);
  l.push_back(s[s.size()-1]);
  l.push_back(s[s.size()-2]);
 
  REP(i,2,s.size())
    {
      for(int n=u.size();n>=2 && ccw(u[n-2],u[n-1],s[i]) != CLOCKWISE;n--)
    {
      u.pop_back();
    }
      u.push_back(s[i]);
    }
 
  for(int i=s.size()-3;i>=0;i--)
    {
      for(int n=l.size();n>=2 && ccw(l[n-2],l[n-1],s[i]) != CLOCKWISE;n--)
    {
      l.pop_back();
    }
      l.push_back(s[i]);
    }
 
  reverse(l.begin(),l.end());
  for(int i=u.size()-2;i>=1;i--)l.push_back(u[i]);
  reverse(l.begin(),l.end());
 

  vector<Point> ret;
 
  bool f = false;
  rep(i,l.size())
    {
      if(l[i].index == now.index)f = true;
      if(f == false)continue;
      ret.push_back(l[i]);
      rep(j,s.size())
    {
      if(s[j].index == l[i].index || s[j].index == l[(i+1)%l.size()].index)continue;
      if(getDistanceSP(Segment(l[i],l[(i+1)%l.size()]),s[j]) == ON_SEGMENT)ret.push_back(s[j]);
    }
    }
 
  rep(i,l.size())
    {
      if(l[i].index == now.index)f = false;
      if(f == false)break;
      ret.push_back(l[i]);
 
      rep(j,s.size())
    {
      if(s[j].index == l[i].index || s[j].index == l[(i+1)%l.size()].index)continue;
      if(getDistanceSP(Segment(l[i],l[(i+1)%l.size()]),s[j]) == ON_SEGMENT)ret.push_back(s[j]);
    }
 
    }
 
 
  return ret;
}

vector<Point> convex_hull(vector<Point> ps) {
  int n = ps.size(), k = 0;
  sort(ps.begin(), ps.end());
  vector<Point> ch(2*n);
  for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
    while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--]) // upper-hull
    while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  ch.resize(k-1);
  return ch;
} 

 
int n;
vector<Point> input;
 
void inputt()
{
  input.clear();
  input.resize(n);
  rep(i,n)
    {
      cin >> input[i].x >> input[i].y;
      input[i].index = i; 
    }
}
  
void solve()
{
  bool used[n];
  rep(i,n)used[i] = false;
  double L = 0;
  Point cur = Point(0,0); 
  cur.index = -1; 

  rep(_,n)
    {
      vector<Point> toConvex;
      rep(i,n)
	{
	  if(used[i])continue;
	  toConvex.push_back(input[i]);
	}
      toConvex.push_back(cur);

      toConvex = convex_hull(toConvex);
      reverse(toConvex.begin(),toConvex.end());

      vector<Point> tmp;
      rep(j,toConvex.size())
	{
	  tmp.push_back(toConvex[j]);
	  rep(i,n)
	    {
	      if(used[i])continue;
	      if(toConvex[j].index == input[i].index || toConvex[(j+1)%toConvex.size()].index == input[i].index)continue;
	      if(equals(getDistanceSP(Segment(toConvex[j],toConvex[(j+1)%toConvex.size()]),input[i]),0))
		{
		  tmp.push_back(input[i]);
		}
	    }
	}
      toConvex = tmp;

      
      cout << "toConvex----- cur : " << cur.x << "," << cur.y << endl;
      rep(i,toConvex.size())
      {
	  cout << toConvex[i].x << "," << toConvex[i].y  << " " << toConvex[i].index<< endl;
	}
      cout << endl;
      

      int next = -inf;
      rep(i,toConvex.size())
	{
	  if(toConvex[i].index == cur.index)
	    {
	      next = toConvex[(i+1)%toConvex.size()].index;
	      break;
	    }
	}
      
      assert(next != -inf);
      cout << "next = " << next << " : " << input[next].x << "," << input[next].y << endl;
      used[next] = true;
      L += sqrt(norm(cur-input[next]));
      cur = input[next];

    }

  L *= 10.0;
  L = round(L);
  L /= 10.0;
  cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
}
 
int main()
{
  while(cin >> n,n)
    {
      inputt();

      solve();
 
    }
  return 0;
}

//変数に一旦いれてたらばぐった

*/

#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<cassert>
#include<iomanip>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1 
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define all(n) (n).begin(),(n).end()
#define pow2(a) (a)*(a)
using namespace std;
double EPS = 1e-9;

bool equals(double a,double b)
{
  return fabs((a)-(b)) < EPS;
}

class Point
{
  public:
  int x,y;

  Point(int x = -1,int y = -1): x(x),y(y){}

  Point operator + (Point p ){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (int a){return Point(a*x,a*y);}
  Point operator / (int a){return Point(x/a,y/a);}//※イケメンに限る

  bool operator < (const Point& p) const
  {
    return x != p.x?x<p.x:y<p.y;
  }

};

struct Segment
{
  Point p1,p2;
  Segment(Point p1 = Point(-1,-1),Point p2 = Point(-1,-1)):p1(p1),p2(p2){}
};
typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;


double dot(Point a,Point b)
{
  return a.x*b.x + a.y*b.y;
}

double cross(Point a,Point b)
{
  return a.x*b.y - a.y*b.x;
}

double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}

double getArgV2(Point A,Point B)
{
  //return acos(dot(A,B)/(sqrt(norm(A))*sqrt(norm(B))));
  double a = sqrt(norm(A));
  double b = sqrt(norm(B));
  return acos(dot(A,B)/(a*b));
}

bool cmp(const Point &a,const Point &b)
{
  if(a.x != b.x)return a.x < b.x;
  return a.y < b.y;
}

Point ps[1000];
bool used[1000];

int main()
{
 
  int n;
  while(cin >> n,n)
    {
      rep(i,n)cin >> ps[i].x >> ps[i].y;
      Point cur(0,0);
      Point cur2(0,-500);
      double L = 0;
      int last = n;

      rep(_,n)
	{
	  /*
	  cout << "remain"<<endl;
	  rep(i,last)
	    {
	      cout << ps[i].x << "," << ps[i].y << endl;
	    }
	  cout << endl;
	  */
	  int next = 0;
	  REP(i,1,last)
	    {
	      if(equals(atan2(ps[next].y-cur.y,ps[next].x-cur.x),atan2(ps[i].y-cur.y,ps[i].x-cur.x)))
	      //if(equals(getArgV2(cur-cur2,ps[next]-cur), getArgV2(cur-cur2,ps[i]-cur)))
		{
		  if(pow2(cur.x-ps[next].x)+pow2(cur.y-ps[next].y) > pow2(cur.x-ps[i].x)+pow2(cur.y-ps[i].y))
		    {
		      next = i;
		    }
		}
	      else if(getArgV2(cur-cur2,ps[next]-cur) > getArgV2(cur-cur2,ps[i]-cur))
		{
		  next = i;
		}
	    }
	  //cout << "erase : " << ps[next].x << "," << ps[next].y << endl;
	  L += sqrt(pow2(cur.x-ps[next].x)+pow2(cur.y-ps[next].y));
	  cur2 = cur;
	  cur = ps[next];
	  ps[next] = ps[last-1];
	  last--;
	}
      
      L *= 10;
      L = round(L);
      L /= 10.0;
      cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
      //printf("%.1f\n",L);
    }
  return 0;
}


/*
int main()
{
  Point A = Point(0,10);
  Point B = Point(-10,15);

  cout << atan2(B.y-A.y,B.x-A.x)*180/M_PI << endl;
  B = Point(11,20);
  cout << atan2(B.y-A.y,B.x-A.x)*180/M_PI << endl;


  int n; 
  while(cin >> n,n)
    {
   

      Point cur1 = Point(0,0);
      Point cur2 = Point(0,0);

      rep(i,n)
	{
	  cin >> ps[i].x >> ps[i].y;
	  cout << i << " :: " << ps[i].x << "," << ps[i].y << endl;
	  used[i] = false;
	}
      cout << atan2(ps[5].y-ps[4].y,ps[5].x-ps[4].x)*180/M_PI << endl;
      cout << "##### " << getArgV2(ps[5]-ps[4],ps[4]-Point(0,0))*180/M_PI << endl;
      sort(ps,ps+n,cmp);



      bool f = true;
      double L = 0;
      rep(_,n)
	{
	  if(_ == 0)
	    {
	      L += sqrt(norm(ps[0]-cur1));
	      cur1 = ps[0];
	      used[0] = true;
	      //cout << "L = " << L << endl;
	      continue;
	    }
	  double minArg = inf;
	  double minDist = inf;
	  int minpos = -inf;
	  rep(i,n)
	    {
	      if(used[i])continue;

	      //cout << "cur1(" << cur1.x << "," << cur1.y << ")" << endl;
	      //cout << "cur2(" << cur2.x << "," << cur2.y << ")" << endl;
	      //cout << "ps["<<i<<"](" << ps[i].x << "," << ps[i].y << ")" << endl;

	      double arg = getArgV2(cur1-cur2,ps[i]-cur1);

	      if(f)
		{
		  f = false;
		  minpos = i;
		  minArg = arg;
		  continue;
		}

	      //cout << arg << " ::: " << endl;
	      if(!equals(arg,minArg) && arg < minArg)
		{
		  minpos = i;
		  minArg = arg;
		  minDist = sqrt(norm(cur1-ps[i]));
		}
	      if(equals(arg,minArg) && sqrt(norm(cur1-ps[minpos])) > sqrt(norm(cur1-ps[i])))
		{
		  minDist = sqrt(norm(cur1-ps[i]));
		  minpos = i;
		
		}

	    }
	  //cout << "cur1 (" << cur1.x << "," << cur1.y << ")" << endl;
	  //cout << "phase #" << _ << " " << minpos << "(" << ps[minpos].x << "," << ps[minpos].y << ")" << endl;
	  //cout << "that arg is " << minArg*180/M_PI << endl;

	  //assert(minpos != -inf);
	  used[minpos] = true;
	  L += sqrt(norm(cur1-ps[minpos]));
	  cur2 = cur1;
	  cur1 = ps[minpos];

	  //cout << "L = " << L << endl << endl;
	}
      //L *= 10.0;
      //L = round(L);
      //L /= 10.0;
      //cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
      printf("%.1f\n",L);
    }
  return 0;
}
*/
/*
#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<cassert>
#include<iomanip>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define all(n) (n).begin(),(n).end()

using namespace std;
double EPS = 1e-9;

bool equals(double a,double b)
{
  return fabs((a)-(b)) < EPS;
}

struct Point
{
  double x,y;
  Point(double x=-inf,double y=-inf):x(x),y(y){}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  bool operator < (const Point &b)const
  {
    if(x != b.x)return x < b.x;
    return y < b.y;
  }
};

Point ps[410];
bool use[410];

double toRad(double agl){ return agl*M_PI/180; }

double getArg(Point a,Point bb)
{

}

double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}

int main()
{
  int n;
  while(cin >> n,n)
    {
      rep(i,n)
	{
	  cin >> ps[i].x >> ps[i].y;
	  use[i] = false;
	}
      sort(ps,ps+n);

      Point cur = Point(0,0);
      Point cur2 = Point(0,0);
      double L = 0;
      rep(_,n)
	{
	  if(!_)
	    {
	      cur = ps[0];
	      use[0] = true;
	      L += sqrt(norm(cur-ps[0]));
	      continue;
	    }
	  cout << "cur " << cur.x << "," << cur.y << endl;
	  cout << "cur2 " << cur2.x << "," << cur2.y << endl;
	  int next = -inf;
	  double maxArg = -inf;

	  rep(i,n)
	    {
	      if(use[i])continue;
	      //cout << "i = "<< i << endl;

	      Point cc = cur - cur2;
	      double arg = atan2(ps[i].y-cc.y,ps[i].x-cc.x);

	      if(!equals(arg,toRad(90)) && arg > toRad(90))arg = toRad(-180)-(toRad(180)-arg);
	      cout << i << " arg = " << arg*180/M_PI << " max : " << maxArg << endl;
	      if(!equals(arg,maxArg) && arg > maxArg)
		{
		  maxArg = arg;
		  next = i;
		}
	      else if(equals(arg,maxArg) &&  norm(ps[next]-cur) > norm(ps[i]-cur) )
		{
		  next = i;
		}
	      //cout << endl;
	    }
	  cout << "next = " << next << " " << ps[next].x << "," << ps[next].y << endl;
	  assert(next != -inf);
	  L += sqrt(pow(cur.x-ps[next].x,2)+pow(cur.y-ps[next].y,2));
	

	  cur2 = cur;
	  cur = ps[next];
	  use[next] = true;
	  cout << endl << endl;
	}

      printf("%.1f\n",L);
    }
  return 0;
}





*/
accuracy: 1
time_ms: 20
memory_kb: 1376
final_rank: 9

code_snippet: /*
#include<iostream>
#include<cstdio>
#include<cmath>
#include<sstream>
#include<algorithm>
#include<cassert>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define F first
#define S second
#define all(n) (n).begin(),(n).end()
#define EPS (1e-8)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a,b) (fabs((a)-(b)) < EPS)
using namespace std;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<vi> vvi;
struct Point
{
  double x,y;
  int index;
  Point(double x=-inf,double y=-inf):x(x),y(y){}
 
  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double p){return Point(x*p,y*p);}
 
  bool operator < (const Point& p)const
  {
    return !equals(x,p.x)?x < p.x:y > p.y;
  }
  bool operator == (const Point &p)const
  {
    return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
  }
};
 
struct Segment
{
  Point p1,p2;
  Segment(Point p1=Point(-inf,-inf),Point p2=Point(-inf,-inf)):p1(p1),p2(p2){}
};
 
typedef vector<Point> Polygon;
typedef Segment Line;
typedef vector<Point> Polygon;
 
double dot(Point a,Point b)
{
  return a.x*b.x+a.y*b.y;
}
 
double cross(Point a,Point b)
{
  return a.x*b.y-a.y*b.x;
}
 
double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}
 
double toRad(double agl)
{
  return agl*M_PI/180.0;
}
 
int ccw(Point p0,Point p1,Point p2)
{
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) <-EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS) return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}
 
 
bool PointEquals(Point a,Point b)
{
  return equals(a.x,b.x) && equals(a.y,b.y);
}
 
double abs(Point a)
{
  return sqrt(norm(a));
}
 
double getDistanceLP(Line s,Point p)
{
  return abs(cross(s.p2-s.p1,p-s.p1))/abs(s.p2-s.p1);
}
 
double getDistanceSP(Segment s,Point p)
{
  if(dot(s.p2-s.p1,p-s.p1) < 0.0)return abs(p-s.p1);
  if(dot(s.p1-s.p2,p-s.p2) < 0.0)return abs(p-s.p2);
  return getDistanceLP(s,p);
}
 
Polygon andrewScan(Polygon s,Point now)
{
  Polygon u,l;
  if(s.size() < 3)return s;
  sort(all(s));
 
  u.push_back(s[0]);
  u.push_back(s[1]);
  l.push_back(s[s.size()-1]);
  l.push_back(s[s.size()-2]);
 
  REP(i,2,s.size())
    {
      for(int n=u.size();n>=2 && ccw(u[n-2],u[n-1],s[i]) != CLOCKWISE;n--)
    {
      u.pop_back();
    }
      u.push_back(s[i]);
    }
 
  for(int i=s.size()-3;i>=0;i--)
    {
      for(int n=l.size();n>=2 && ccw(l[n-2],l[n-1],s[i]) != CLOCKWISE;n--)
    {
      l.pop_back();
    }
      l.push_back(s[i]);
    }
 
  reverse(l.begin(),l.end());
  for(int i=u.size()-2;i>=1;i--)l.push_back(u[i]);
  reverse(l.begin(),l.end());
 

  vector<Point> ret;
 
  bool f = false;
  rep(i,l.size())
    {
      if(l[i].index == now.index)f = true;
      if(f == false)continue;
      ret.push_back(l[i]);
      rep(j,s.size())
    {
      if(s[j].index == l[i].index || s[j].index == l[(i+1)%l.size()].index)continue;
      if(getDistanceSP(Segment(l[i],l[(i+1)%l.size()]),s[j]) == ON_SEGMENT)ret.push_back(s[j]);
    }
    }
 
  rep(i,l.size())
    {
      if(l[i].index == now.index)f = false;
      if(f == false)break;
      ret.push_back(l[i]);
 
      rep(j,s.size())
    {
      if(s[j].index == l[i].index || s[j].index == l[(i+1)%l.size()].index)continue;
      if(getDistanceSP(Segment(l[i],l[(i+1)%l.size()]),s[j]) == ON_SEGMENT)ret.push_back(s[j]);
    }
 
    }
 
 
  return ret;
}

vector<Point> convex_hull(vector<Point> ps) {
  int n = ps.size(), k = 0;
  sort(ps.begin(), ps.end());
  vector<Point> ch(2*n);
  for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
    while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--]) // upper-hull
    while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  ch.resize(k-1);
  return ch;
} 

 
int n;
vector<Point> input;
 
void inputt()
{
  input.clear();
  input.resize(n);
  rep(i,n)
    {
      cin >> input[i].x >> input[i].y;
      input[i].index = i; 
    }
}
  
void solve()
{
  bool used[n];
  rep(i,n)used[i] = false;
  double L = 0;
  Point cur = Point(0,0); 
  cur.index = -1; 

  rep(_,n)
    {
      vector<Point> toConvex;
      rep(i,n)
	{
	  if(used[i])continue;
	  toConvex.push_back(input[i]);
	}
      toConvex.push_back(cur);

      toConvex = convex_hull(toConvex);
      reverse(toConvex.begin(),toConvex.end());

      vector<Point> tmp;
      rep(j,toConvex.size())
	{
	  tmp.push_back(toConvex[j]);
	  rep(i,n)
	    {
	      if(used[i])continue;
	      if(toConvex[j].index == input[i].index || toConvex[(j+1)%toConvex.size()].index == input[i].index)continue;
	      if(equals(getDistanceSP(Segment(toConvex[j],toConvex[(j+1)%toConvex.size()]),input[i]),0))
		{
		  tmp.push_back(input[i]);
		}
	    }
	}
      toConvex = tmp;

      
      cout << "toConvex----- cur : " << cur.x << "," << cur.y << endl;
      rep(i,toConvex.size())
      {
	  cout << toConvex[i].x << "," << toConvex[i].y  << " " << toConvex[i].index<< endl;
	}
      cout << endl;
      

      int next = -inf;
      rep(i,toConvex.size())
	{
	  if(toConvex[i].index == cur.index)
	    {
	      next = toConvex[(i+1)%toConvex.size()].index;
	      break;
	    }
	}
      
      assert(next != -inf);
      cout << "next = " << next << " : " << input[next].x << "," << input[next].y << endl;
      used[next] = true;
      L += sqrt(norm(cur-input[next]));
      cur = input[next];

    }

  L *= 10.0;
  L = round(L);
  L /= 10.0;
  cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
}
 
int main()
{
  while(cin >> n,n)
    {
      inputt();

      solve();
 
    }
  return 0;
}

//テ・ツ、ツ嘉ヲツ閉ーテ」ツ?ォテ、ツクツ?ヲツ猟ヲテ」ツ??」ツつ古」ツ?ヲテ」ツ?淌」ツつ嘉」ツ?ーテ」ツ?静」ツ?」テ」ツ??

*/

#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<cassert>
#include<iomanip>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1 
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define all(n) (n).begin(),(n).end()
#define pow2(a) (a)*(a)
using namespace std;
double EPS = 1e-9;

bool equals(double a,double b)
{
  return fabs((a)-(b)) < EPS;
}

class Point
{
  public:
  int x,y;

  Point(int x = -1,int y = -1): x(x),y(y){}

  Point operator + (Point p ){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (int a){return Point(a*x,a*y);}
  Point operator / (int a){return Point(x/a,y/a);}

  bool operator < (const Point& p) const
  {
    return x != p.x?x<p.x:y<p.y;
  }

};

struct Segment
{
  Point p1,p2;
  Segment(Point p1 = Point(-1,-1),Point p2 = Point(-1,-1)):p1(p1),p2(p2){}
};
typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;


double dot(Point a,Point b)
{
  return a.x*b.x + a.y*b.y;
}

double cross(Point a,Point b)
{
  return a.x*b.y - a.y*b.x;
}

double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}

double getArgV2(Point A,Point B)
{
  return acos(dot(A,B)/(sqrt(norm(A))*sqrt(norm(B))));
  double a = sqrt(norm(A));
  double b = sqrt(norm(B));
  return acos(dot(A,B)/(a*b));
}

bool cmp(const Point &a,const Point &b)
{
  if(a.x != b.x)return a.x < b.x;
  return a.y < b.y;
}

Point ps[1000];
bool used[1000];

int main()
{
 
  int n;
  while(cin >> n,n)
    {
      rep(i,n)cin >> ps[i].x >> ps[i].y;
      Point cur(0,0);
      Point cur2(0,-500);
      double L = 0;
      int last = n;

      rep(_,n)
	{
	  /*
	  cout << "remain"<<endl;
	  rep(i,last)
	    {
	      cout << ps[i].x << "," << ps[i].y << endl;
	    }
	  cout << endl;
	  */
	  int next = 0;
	  REP(i,1,last)
	    {
	      if(equals(atan2(ps[next].y-cur.y,ps[next].x-cur.x),atan2(ps[i].y-cur.y,ps[i].x-cur.x)))
	      //if(equals(getArgV2(cur-cur2,ps[next]-cur), getArgV2(cur-cur2,ps[i]-cur)))
		{
		  if(pow2(cur.x-ps[next].x)+pow2(cur.y-ps[next].y) > pow2(cur.x-ps[i].x)+pow2(cur.y-ps[i].y))
		    {
		      next = i;
		    }
		}
	      else if(getArgV2(cur-cur2,ps[next]-cur) > getArgV2(cur-cur2,ps[i]-cur))
		{
		  next = i;
		}
	    }
	  //cout << "erase : " << ps[next].x << "," << ps[next].y << endl;
	  L += sqrt(pow2(cur.x-ps[next].x)+pow2(cur.y-ps[next].y));
	  cur2 = cur;
	  cur = ps[next];
	  ps[next] = ps[last-1];
	  last--;
	}
      
      L *= 10;
      L = round(L);
      L /= 10.0;
      cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
      //printf("%.1f\n",L);
    }
  return 0;
}


/*
int main()
{
  Point A = Point(0,10);
  Point B = Point(-10,15);

  cout << atan2(B.y-A.y,B.x-A.x)*180/M_PI << endl;
  B = Point(11,20);
  cout << atan2(B.y-A.y,B.x-A.x)*180/M_PI << endl;


  int n; 
  while(cin >> n,n)
    {
   

      Point cur1 = Point(0,0);
      Point cur2 = Point(0,0);

      rep(i,n)
	{
	  cin >> ps[i].x >> ps[i].y;
	  cout << i << " :: " << ps[i].x << "," << ps[i].y << endl;
	  used[i] = false;
	}
      cout << atan2(ps[5].y-ps[4].y,ps[5].x-ps[4].x)*180/M_PI << endl;
      cout << "##### " << getArgV2(ps[5]-ps[4],ps[4]-Point(0,0))*180/M_PI << endl;
      sort(ps,ps+n,cmp);



      bool f = true;
      double L = 0;
      rep(_,n)
	{
	  if(_ == 0)
	    {
	      L += sqrt(norm(ps[0]-cur1));
	      cur1 = ps[0];
	      used[0] = true;
	      //cout << "L = " << L << endl;
	      continue;
	    }
	  double minArg = inf;
	  double minDist = inf;
	  int minpos = -inf;
	  rep(i,n)
	    {
	      if(used[i])continue;

	      //cout << "cur1(" << cur1.x << "," << cur1.y << ")" << endl;
	      //cout << "cur2(" << cur2.x << "," << cur2.y << ")" << endl;
	      //cout << "ps["<<i<<"](" << ps[i].x << "," << ps[i].y << ")" << endl;

	      double arg = getArgV2(cur1-cur2,ps[i]-cur1);

	      if(f)
		{
		  f = false;
		  minpos = i;
		  minArg = arg;
		  continue;
		}

	      //cout << arg << " ::: " << endl;
	      if(!equals(arg,minArg) && arg < minArg)
		{
		  minpos = i;
		  minArg = arg;
		  minDist = sqrt(norm(cur1-ps[i]));
		}
	      if(equals(arg,minArg) && sqrt(norm(cur1-ps[minpos])) > sqrt(norm(cur1-ps[i])))
		{
		  minDist = sqrt(norm(cur1-ps[i]));
		  minpos = i;
		
		}

	    }
	  //cout << "cur1 (" << cur1.x << "," << cur1.y << ")" << endl;
	  //cout << "phase #" << _ << " " << minpos << "(" << ps[minpos].x << "," << ps[minpos].y << ")" << endl;
	  //cout << "that arg is " << minArg*180/M_PI << endl;

	  //assert(minpos != -inf);
	  used[minpos] = true;
	  L += sqrt(norm(cur1-ps[minpos]));
	  cur2 = cur1;
	  cur1 = ps[minpos];

	  //cout << "L = " << L << endl << endl;
	}
      //L *= 10.0;
      //L = round(L);
      //L /= 10.0;
      //cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
      printf("%.1f\n",L);
    }
  return 0;
}
*/
/*
#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<cassert>
#include<iomanip>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define all(n) (n).begin(),(n).end()

using namespace std;
double EPS = 1e-9;

bool equals(double a,double b)
{
  return fabs((a)-(b)) < EPS;
}

struct Point
{
  double x,y;
  Point(double x=-inf,double y=-inf):x(x),y(y){}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  bool operator < (const Point &b)const
  {
    if(x != b.x)return x < b.x;
    return y < b.y;
  }
};

Point ps[410];
bool use[410];

double toRad(double agl){ return agl*M_PI/180; }

double getArg(Point a,Point bb)
{

}

double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}

int main()
{
  int n;
  while(cin >> n,n)
    {
      rep(i,n)
	{
	  cin >> ps[i].x >> ps[i].y;
	  use[i] = false;
	}
      sort(ps,ps+n);

      Point cur = Point(0,0);
      Point cur2 = Point(0,0);
      double L = 0;
      rep(_,n)
	{
	  if(!_)
	    {
	      cur = ps[0];
	      use[0] = true;
	      L += sqrt(norm(cur-ps[0]));
	      continue;
	    }
	  cout << "cur " << cur.x << "," << cur.y << endl;
	  cout << "cur2 " << cur2.x << "," << cur2.y << endl;
	  int next = -inf;
	  double maxArg = -inf;

	  rep(i,n)
	    {
	      if(use[i])continue;
	      //cout << "i = "<< i << endl;

	      Point cc = cur - cur2;
	      double arg = atan2(ps[i].y-cc.y,ps[i].x-cc.x);

	      if(!equals(arg,toRad(90)) && arg > toRad(90))arg = toRad(-180)-(toRad(180)-arg);
	      cout << i << " arg = " << arg*180/M_PI << " max : " << maxArg << endl;
	      if(!equals(arg,maxArg) && arg > maxArg)
		{
		  maxArg = arg;
		  next = i;
		}
	      else if(equals(arg,maxArg) &&  norm(ps[next]-cur) > norm(ps[i]-cur) )
		{
		  next = i;
		}
	      //cout << endl;
	    }
	  cout << "next = " << next << " " << ps[next].x << "," << ps[next].y << endl;
	  assert(next != -inf);
	  L += sqrt(pow(cur.x-ps[next].x,2)+pow(cur.y-ps[next].y,2));
	

	  cur2 = cur;
	  cur = ps[next];
	  use[next] = true;
	  cout << endl << endl;
	}

      printf("%.1f\n",L);
    }
  return 0;
}





*/
accuracy: 1
time_ms: 20
memory_kb: 1376
final_rank: 9

code_snippet: /*
#include<iostream>
#include<cstdio>
#include<cmath>
#include<sstream>
#include<algorithm>
#include<cassert>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define F first
#define S second
#define all(n) (n).begin(),(n).end()
#define EPS (1e-8)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a,b) (fabs((a)-(b)) < EPS)
using namespace std;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<vi> vvi;
struct Point
{
  double x,y;
  int index;
  Point(double x=-inf,double y=-inf):x(x),y(y){}
 
  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double p){return Point(x*p,y*p);}
 
  bool operator < (const Point& p)const
  {
    return !equals(x,p.x)?x < p.x:y > p.y;
  }
  bool operator == (const Point &p)const
  {
    return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
  }
};
 
struct Segment
{
  Point p1,p2;
  Segment(Point p1=Point(-inf,-inf),Point p2=Point(-inf,-inf)):p1(p1),p2(p2){}
};
 
typedef vector<Point> Polygon;
typedef Segment Line;
typedef vector<Point> Polygon;
 
double dot(Point a,Point b)
{
  return a.x*b.x+a.y*b.y;
}
 
double cross(Point a,Point b)
{
  return a.x*b.y-a.y*b.x;
}
 
double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}
 
double toRad(double agl)
{
  return agl*M_PI/180.0;
}
 
int ccw(Point p0,Point p1,Point p2)
{
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) <-EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS) return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}
 
 
bool PointEquals(Point a,Point b)
{
  return equals(a.x,b.x) && equals(a.y,b.y);
}
 
double abs(Point a)
{
  return sqrt(norm(a));
}
 
double getDistanceLP(Line s,Point p)
{
  return abs(cross(s.p2-s.p1,p-s.p1))/abs(s.p2-s.p1);
}
 
double getDistanceSP(Segment s,Point p)
{
  if(dot(s.p2-s.p1,p-s.p1) < 0.0)return abs(p-s.p1);
  if(dot(s.p1-s.p2,p-s.p2) < 0.0)return abs(p-s.p2);
  return getDistanceLP(s,p);
}
 
Polygon andrewScan(Polygon s,Point now)
{
  Polygon u,l;
  if(s.size() < 3)return s;
  sort(all(s));
 
  u.push_back(s[0]);
  u.push_back(s[1]);
  l.push_back(s[s.size()-1]);
  l.push_back(s[s.size()-2]);
 
  REP(i,2,s.size())
    {
      for(int n=u.size();n>=2 && ccw(u[n-2],u[n-1],s[i]) != CLOCKWISE;n--)
    {
      u.pop_back();
    }
      u.push_back(s[i]);
    }
 
  for(int i=s.size()-3;i>=0;i--)
    {
      for(int n=l.size();n>=2 && ccw(l[n-2],l[n-1],s[i]) != CLOCKWISE;n--)
    {
      l.pop_back();
    }
      l.push_back(s[i]);
    }
 
  reverse(l.begin(),l.end());
  for(int i=u.size()-2;i>=1;i--)l.push_back(u[i]);
  reverse(l.begin(),l.end());
 

  vector<Point> ret;
 
  bool f = false;
  rep(i,l.size())
    {
      if(l[i].index == now.index)f = true;
      if(f == false)continue;
      ret.push_back(l[i]);
      rep(j,s.size())
    {
      if(s[j].index == l[i].index || s[j].index == l[(i+1)%l.size()].index)continue;
      if(getDistanceSP(Segment(l[i],l[(i+1)%l.size()]),s[j]) == ON_SEGMENT)ret.push_back(s[j]);
    }
    }
 
  rep(i,l.size())
    {
      if(l[i].index == now.index)f = false;
      if(f == false)break;
      ret.push_back(l[i]);
 
      rep(j,s.size())
    {
      if(s[j].index == l[i].index || s[j].index == l[(i+1)%l.size()].index)continue;
      if(getDistanceSP(Segment(l[i],l[(i+1)%l.size()]),s[j]) == ON_SEGMENT)ret.push_back(s[j]);
    }
 
    }
 
 
  return ret;
}

vector<Point> convex_hull(vector<Point> ps) {
  int n = ps.size(), k = 0;
  sort(ps.begin(), ps.end());
  vector<Point> ch(2*n);
  for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
    while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--]) // upper-hull
    while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  ch.resize(k-1);
  return ch;
} 

 
int n;
vector<Point> input;
 
void inputt()
{
  input.clear();
  input.resize(n);
  rep(i,n)
    {
      cin >> input[i].x >> input[i].y;
      input[i].index = i; 
    }
}
  
void solve()
{
  bool used[n];
  rep(i,n)used[i] = false;
  double L = 0;
  Point cur = Point(0,0); 
  cur.index = -1; 

  rep(_,n)
    {
      vector<Point> toConvex;
      rep(i,n)
	{
	  if(used[i])continue;
	  toConvex.push_back(input[i]);
	}
      toConvex.push_back(cur);

      toConvex = convex_hull(toConvex);
      reverse(toConvex.begin(),toConvex.end());

      vector<Point> tmp;
      rep(j,toConvex.size())
	{
	  tmp.push_back(toConvex[j]);
	  rep(i,n)
	    {
	      if(used[i])continue;
	      if(toConvex[j].index == input[i].index || toConvex[(j+1)%toConvex.size()].index == input[i].index)continue;
	      if(equals(getDistanceSP(Segment(toConvex[j],toConvex[(j+1)%toConvex.size()]),input[i]),0))
		{
		  tmp.push_back(input[i]);
		}
	    }
	}
      toConvex = tmp;

      
      cout << "toConvex----- cur : " << cur.x << "," << cur.y << endl;
      rep(i,toConvex.size())
      {
	  cout << toConvex[i].x << "," << toConvex[i].y  << " " << toConvex[i].index<< endl;
	}
      cout << endl;
      

      int next = -inf;
      rep(i,toConvex.size())
	{
	  if(toConvex[i].index == cur.index)
	    {
	      next = toConvex[(i+1)%toConvex.size()].index;
	      break;
	    }
	}
      
      assert(next != -inf);
      cout << "next = " << next << " : " << input[next].x << "," << input[next].y << endl;
      used[next] = true;
      L += sqrt(norm(cur-input[next]));
      cur = input[next];

    }

  L *= 10.0;
  L = round(L);
  L /= 10.0;
  cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
}
 
int main()
{
  while(cin >> n,n)
    {
      inputt();

      solve();
 
    }
  return 0;
}

//変数に一旦いれてたらばぐった

*/

#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<cassert>
#include<iomanip>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1 
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define all(n) (n).begin(),(n).end()
#define pow2(a) (a)*(a)
using namespace std;
double EPS = 1e-9;

bool equals(double a,double b)
{
  return fabs((a)-(b)) < EPS;
}

class Point
{
  public:
  int x,y;

  Point(int x = -1,int y = -1): x(x),y(y){}

  Point operator + (Point p ){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (int a){return Point(a*x,a*y);}
  Point operator / (int a){return Point(x/a,y/a);}//※イケメンに限る

  bool operator < (const Point& p) const
  {
    return x != p.x?x<p.x:y<p.y;
  }

};

struct Segment
{
  Point p1,p2;
  Segment(Point p1 = Point(-1,-1),Point p2 = Point(-1,-1)):p1(p1),p2(p2){}
};
typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;


double dot(Point a,Point b)
{
  return a.x*b.x + a.y*b.y;
}

double cross(Point a,Point b)
{
  return a.x*b.y - a.y*b.x;
}

double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}

double getArgV2(Point A,Point B)
{
  return acos(dot(A,B)/(sqrt(norm(A))*sqrt(norm(B))));
  double a = sqrt(norm(A));
  double b = sqrt(norm(B));
  return acos(dot(A,B)/(a*b));
}

bool cmp(const Point &a,const Point &b)
{
  if(a.x != b.x)return a.x < b.x;
  return a.y < b.y;
}

Point ps[1000];
bool used[1000];

int main()
{
 
  int n;
  while(cin >> n,n)
    {
      rep(i,n)cin >> ps[i].x >> ps[i].y;
      Point cur(0,0);
      Point cur2(0,-500);
      double L = 0;
      int last = n;

      rep(_,n)
	{
	  /*
	  cout << "remain"<<endl;
	  rep(i,last)
	    {
	      cout << ps[i].x << "," << ps[i].y << endl;
	    }
	  cout << endl;
	  */
	  int next = 0;
	  REP(i,1,last)
	    {
	      if(equals(atan2(ps[next].y-cur.y,ps[next].x-cur.x),atan2(ps[i].y-cur.y,ps[i].x-cur.x)))
	      //if(equals(getArgV2(cur-cur2,ps[next]-cur), getArgV2(cur-cur2,ps[i]-cur)))
		{
		  if(pow2(cur.x-ps[next].x)+pow2(cur.y-ps[next].y) > pow2(cur.x-ps[i].x)+pow2(cur.y-ps[i].y))
		    {
		      next = i;
		    }
		}
	      else if(getArgV2(cur-cur2,ps[next]-cur) > getArgV2(cur-cur2,ps[i]-cur))
		{
		  next = i;
		}
	    }
	  //cout << "erase : " << ps[next].x << "," << ps[next].y << endl;
	  L += sqrt(pow2(cur.x-ps[next].x)+pow2(cur.y-ps[next].y));
	  cur2 = cur;
	  cur = ps[next];
	  ps[next] = ps[last-1];
	  last--;
	}
      
      L *= 10;
      L = round(L);
      L /= 10.0;
      cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
      //printf("%.1f\n",L);
    }
  return 0;
}


/*
int main()
{
  Point A = Point(0,10);
  Point B = Point(-10,15);

  cout << atan2(B.y-A.y,B.x-A.x)*180/M_PI << endl;
  B = Point(11,20);
  cout << atan2(B.y-A.y,B.x-A.x)*180/M_PI << endl;


  int n; 
  while(cin >> n,n)
    {
   

      Point cur1 = Point(0,0);
      Point cur2 = Point(0,0);

      rep(i,n)
	{
	  cin >> ps[i].x >> ps[i].y;
	  cout << i << " :: " << ps[i].x << "," << ps[i].y << endl;
	  used[i] = false;
	}
      cout << atan2(ps[5].y-ps[4].y,ps[5].x-ps[4].x)*180/M_PI << endl;
      cout << "##### " << getArgV2(ps[5]-ps[4],ps[4]-Point(0,0))*180/M_PI << endl;
      sort(ps,ps+n,cmp);



      bool f = true;
      double L = 0;
      rep(_,n)
	{
	  if(_ == 0)
	    {
	      L += sqrt(norm(ps[0]-cur1));
	      cur1 = ps[0];
	      used[0] = true;
	      //cout << "L = " << L << endl;
	      continue;
	    }
	  double minArg = inf;
	  double minDist = inf;
	  int minpos = -inf;
	  rep(i,n)
	    {
	      if(used[i])continue;

	      //cout << "cur1(" << cur1.x << "," << cur1.y << ")" << endl;
	      //cout << "cur2(" << cur2.x << "," << cur2.y << ")" << endl;
	      //cout << "ps["<<i<<"](" << ps[i].x << "," << ps[i].y << ")" << endl;

	      double arg = getArgV2(cur1-cur2,ps[i]-cur1);

	      if(f)
		{
		  f = false;
		  minpos = i;
		  minArg = arg;
		  continue;
		}

	      //cout << arg << " ::: " << endl;
	      if(!equals(arg,minArg) && arg < minArg)
		{
		  minpos = i;
		  minArg = arg;
		  minDist = sqrt(norm(cur1-ps[i]));
		}
	      if(equals(arg,minArg) && sqrt(norm(cur1-ps[minpos])) > sqrt(norm(cur1-ps[i])))
		{
		  minDist = sqrt(norm(cur1-ps[i]));
		  minpos = i;
		
		}

	    }
	  //cout << "cur1 (" << cur1.x << "," << cur1.y << ")" << endl;
	  //cout << "phase #" << _ << " " << minpos << "(" << ps[minpos].x << "," << ps[minpos].y << ")" << endl;
	  //cout << "that arg is " << minArg*180/M_PI << endl;

	  //assert(minpos != -inf);
	  used[minpos] = true;
	  L += sqrt(norm(cur1-ps[minpos]));
	  cur2 = cur1;
	  cur1 = ps[minpos];

	  //cout << "L = " << L << endl << endl;
	}
      //L *= 10.0;
      //L = round(L);
      //L /= 10.0;
      //cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
      printf("%.1f\n",L);
    }
  return 0;
}
*/
/*
#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<cassert>
#include<iomanip>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define all(n) (n).begin(),(n).end()

using namespace std;
double EPS = 1e-9;

bool equals(double a,double b)
{
  return fabs((a)-(b)) < EPS;
}

struct Point
{
  double x,y;
  Point(double x=-inf,double y=-inf):x(x),y(y){}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  bool operator < (const Point &b)const
  {
    if(x != b.x)return x < b.x;
    return y < b.y;
  }
};

Point ps[410];
bool use[410];

double toRad(double agl){ return agl*M_PI/180; }

double getArg(Point a,Point bb)
{

}

double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}

int main()
{
  int n;
  while(cin >> n,n)
    {
      rep(i,n)
	{
	  cin >> ps[i].x >> ps[i].y;
	  use[i] = false;
	}
      sort(ps,ps+n);

      Point cur = Point(0,0);
      Point cur2 = Point(0,0);
      double L = 0;
      rep(_,n)
	{
	  if(!_)
	    {
	      cur = ps[0];
	      use[0] = true;
	      L += sqrt(norm(cur-ps[0]));
	      continue;
	    }
	  cout << "cur " << cur.x << "," << cur.y << endl;
	  cout << "cur2 " << cur2.x << "," << cur2.y << endl;
	  int next = -inf;
	  double maxArg = -inf;

	  rep(i,n)
	    {
	      if(use[i])continue;
	      //cout << "i = "<< i << endl;

	      Point cc = cur - cur2;
	      double arg = atan2(ps[i].y-cc.y,ps[i].x-cc.x);

	      if(!equals(arg,toRad(90)) && arg > toRad(90))arg = toRad(-180)-(toRad(180)-arg);
	      cout << i << " arg = " << arg*180/M_PI << " max : " << maxArg << endl;
	      if(!equals(arg,maxArg) && arg > maxArg)
		{
		  maxArg = arg;
		  next = i;
		}
	      else if(equals(arg,maxArg) &&  norm(ps[next]-cur) > norm(ps[i]-cur) )
		{
		  next = i;
		}
	      //cout << endl;
	    }
	  cout << "next = " << next << " " << ps[next].x << "," << ps[next].y << endl;
	  assert(next != -inf);
	  L += sqrt(pow(cur.x-ps[next].x,2)+pow(cur.y-ps[next].y,2));
	

	  cur2 = cur;
	  cur = ps[next];
	  use[next] = true;
	  cout << endl << endl;
	}

      printf("%.1f\n",L);
    }
  return 0;
}





*/
accuracy: 1
time_ms: 10
memory_kb: 1376
final_rank: 8

code_snippet: /*
#include<iostream>
#include<cstdio>
#include<cmath>
#include<sstream>
#include<algorithm>
#include<cassert>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define F first
#define S second
#define all(n) (n).begin(),(n).end()
#define EPS (1e-8)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a,b) (fabs((a)-(b)) < EPS)
using namespace std;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<vi> vvi;
struct Point
{
  double x,y;
  int index;
  Point(double x=-inf,double y=-inf):x(x),y(y){}
 
  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double p){return Point(x*p,y*p);}
 
  bool operator < (const Point& p)const
  {
    return !equals(x,p.x)?x < p.x:y > p.y;
  }
  bool operator == (const Point &p)const
  {
    return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
  }
};
 
struct Segment
{
  Point p1,p2;
  Segment(Point p1=Point(-inf,-inf),Point p2=Point(-inf,-inf)):p1(p1),p2(p2){}
};
 
typedef vector<Point> Polygon;
typedef Segment Line;
typedef vector<Point> Polygon;
 
double dot(Point a,Point b)
{
  return a.x*b.x+a.y*b.y;
}
 
double cross(Point a,Point b)
{
  return a.x*b.y-a.y*b.x;
}
 
double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}
 
double toRad(double agl)
{
  return agl*M_PI/180.0;
}
 
int ccw(Point p0,Point p1,Point p2)
{
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) <-EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS) return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}
 
 
bool PointEquals(Point a,Point b)
{
  return equals(a.x,b.x) && equals(a.y,b.y);
}
 
double abs(Point a)
{
  return sqrt(norm(a));
}
 
double getDistanceLP(Line s,Point p)
{
  return abs(cross(s.p2-s.p1,p-s.p1))/abs(s.p2-s.p1);
}
 
double getDistanceSP(Segment s,Point p)
{
  if(dot(s.p2-s.p1,p-s.p1) < 0.0)return abs(p-s.p1);
  if(dot(s.p1-s.p2,p-s.p2) < 0.0)return abs(p-s.p2);
  return getDistanceLP(s,p);
}
 
Polygon andrewScan(Polygon s,Point now)
{
  Polygon u,l;
  if(s.size() < 3)return s;
  sort(all(s));
 
  u.push_back(s[0]);
  u.push_back(s[1]);
  l.push_back(s[s.size()-1]);
  l.push_back(s[s.size()-2]);
 
  REP(i,2,s.size())
    {
      for(int n=u.size();n>=2 && ccw(u[n-2],u[n-1],s[i]) != CLOCKWISE;n--)
    {
      u.pop_back();
    }
      u.push_back(s[i]);
    }
 
  for(int i=s.size()-3;i>=0;i--)
    {
      for(int n=l.size();n>=2 && ccw(l[n-2],l[n-1],s[i]) != CLOCKWISE;n--)
    {
      l.pop_back();
    }
      l.push_back(s[i]);
    }
 
  reverse(l.begin(),l.end());
  for(int i=u.size()-2;i>=1;i--)l.push_back(u[i]);
  reverse(l.begin(),l.end());
 

  vector<Point> ret;
 
  bool f = false;
  rep(i,l.size())
    {
      if(l[i].index == now.index)f = true;
      if(f == false)continue;
      ret.push_back(l[i]);
      rep(j,s.size())
    {
      if(s[j].index == l[i].index || s[j].index == l[(i+1)%l.size()].index)continue;
      if(getDistanceSP(Segment(l[i],l[(i+1)%l.size()]),s[j]) == ON_SEGMENT)ret.push_back(s[j]);
    }
    }
 
  rep(i,l.size())
    {
      if(l[i].index == now.index)f = false;
      if(f == false)break;
      ret.push_back(l[i]);
 
      rep(j,s.size())
    {
      if(s[j].index == l[i].index || s[j].index == l[(i+1)%l.size()].index)continue;
      if(getDistanceSP(Segment(l[i],l[(i+1)%l.size()]),s[j]) == ON_SEGMENT)ret.push_back(s[j]);
    }
 
    }
 
 
  return ret;
}

vector<Point> convex_hull(vector<Point> ps) {
  int n = ps.size(), k = 0;
  sort(ps.begin(), ps.end());
  vector<Point> ch(2*n);
  for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
    while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--]) // upper-hull
    while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  ch.resize(k-1);
  return ch;
} 

 
int n;
vector<Point> input;
 
void inputt()
{
  input.clear();
  input.resize(n);
  rep(i,n)
    {
      cin >> input[i].x >> input[i].y;
      input[i].index = i; 
    }
}
  
void solve()
{
  bool used[n];
  rep(i,n)used[i] = false;
  double L = 0;
  Point cur = Point(0,0); 
  cur.index = -1; 

  rep(_,n)
    {
      vector<Point> toConvex;
      rep(i,n)
	{
	  if(used[i])continue;
	  toConvex.push_back(input[i]);
	}
      toConvex.push_back(cur);

      toConvex = convex_hull(toConvex);
      reverse(toConvex.begin(),toConvex.end());

      vector<Point> tmp;
      rep(j,toConvex.size())
	{
	  tmp.push_back(toConvex[j]);
	  rep(i,n)
	    {
	      if(used[i])continue;
	      if(toConvex[j].index == input[i].index || toConvex[(j+1)%toConvex.size()].index == input[i].index)continue;
	      if(equals(getDistanceSP(Segment(toConvex[j],toConvex[(j+1)%toConvex.size()]),input[i]),0))
		{
		  tmp.push_back(input[i]);
		}
	    }
	}
      toConvex = tmp;

      
      cout << "toConvex----- cur : " << cur.x << "," << cur.y << endl;
      rep(i,toConvex.size())
      {
	  cout << toConvex[i].x << "," << toConvex[i].y  << " " << toConvex[i].index<< endl;
	}
      cout << endl;
      

      int next = -inf;
      rep(i,toConvex.size())
	{
	  if(toConvex[i].index == cur.index)
	    {
	      next = toConvex[(i+1)%toConvex.size()].index;
	      break;
	    }
	}
      
      assert(next != -inf);
      cout << "next = " << next << " : " << input[next].x << "," << input[next].y << endl;
      used[next] = true;
      L += sqrt(norm(cur-input[next]));
      cur = input[next];

    }

  L *= 10.0;
  L = round(L);
  L /= 10.0;
  cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
}
 
int main()
{
  while(cin >> n,n)
    {
      inputt();

      solve();
 
    }
  return 0;
}

//変数に一旦いれてたらばぐった

*/

#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<cassert>
#include<iomanip>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1 
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define all(n) (n).begin(),(n).end()
#define pow2(a) (a)*(a)
using namespace std;
double EPS = 1e-9;

bool equals(double a,double b)
{
  return fabs((a)-(b)) < EPS;
}

class Point
{
  public:
  int x,y;

  Point(int x = -1,int y = -1): x(x),y(y){}

  Point operator + (Point p ){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (int a){return Point(a*x,a*y);}
  Point operator / (int a){return Point(x/a,y/a);}//※イケメンに限る

  bool operator < (const Point& p) const
  {
    return x != p.x?x<p.x:y<p.y;
  }

};

struct Segment
{
  Point p1,p2;
  Segment(Point p1 = Point(-1,-1),Point p2 = Point(-1,-1)):p1(p1),p2(p2){}
};
typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;


double dot(Point a,Point b)
{
  return a.x*b.x + a.y*b.y;
}

double cross(Point a,Point b)
{
  return a.x*b.y - a.y*b.x;
}

double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}

double getArgV2(Point A,Point B)
{
  return acos(dot(A,B)/(sqrt(norm(A))*sqrt(norm(B))));
  double a = sqrt(norm(A));
  double b = sqrt(norm(B));
  return acos(dot(A,B)/(a*b));
}

bool cmp(const Point &a,const Point &b)
{
  if(a.x != b.x)return a.x < b.x;
  return a.y < b.y;
}

Point ps[1000];
bool used[1000];

int main()
{
 
  int n;
  while(cin >> n,n)
    {
      rep(i,n)cin >> ps[i].x >> ps[i].y;
      Point cur(0,0);
      Point cur2(0,-512);
      double L = 0;
      int last = n;

      rep(_,n)
	{
	  /*
	  cout << "remain"<<endl;
	  rep(i,last)
	    {
	      cout << ps[i].x << "," << ps[i].y << endl;
	    }
	  cout << endl;
	  */
	  int next = 0;
	  REP(i,1,last)
	    {
	      if(equals(atan2(ps[next].y-cur.y,ps[next].x-cur.x),atan2(ps[i].y-cur.y,ps[i].x-cur.x)))
		{
		  if(pow2(cur.x-ps[next].x)+pow2(cur.y-ps[next].y) > pow2(cur.x-ps[i].x)+pow2(cur.y-ps[i].y))
		    {
		      next = i;
		    }
		}
	      else if(getArgV2(cur-cur2,ps[next]-cur) > getArgV2(cur-cur2,ps[i]-cur))
		{
		  next = i;
		}
	    }
	  //cout << "erase : " << ps[next].x << "," << ps[next].y << endl;
	  L += sqrt(pow2(cur.x-ps[next].x)+pow2(cur.y-ps[next].y));
	  cur2 = cur;
	  cur = ps[next];
	  ps[next] = ps[last-1];
	  last--;
	}
      
      L *= 10;
      L = round(L);
      L /= 10.0;
      cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
      //printf("%.1f\n",L);
    }
  return 0;
}


/*
int main()
{
  Point A = Point(0,10);
  Point B = Point(-10,15);

  cout << atan2(B.y-A.y,B.x-A.x)*180/M_PI << endl;
  B = Point(11,20);
  cout << atan2(B.y-A.y,B.x-A.x)*180/M_PI << endl;


  int n; 
  while(cin >> n,n)
    {
   

      Point cur1 = Point(0,0);
      Point cur2 = Point(0,0);

      rep(i,n)
	{
	  cin >> ps[i].x >> ps[i].y;
	  cout << i << " :: " << ps[i].x << "," << ps[i].y << endl;
	  used[i] = false;
	}
      cout << atan2(ps[5].y-ps[4].y,ps[5].x-ps[4].x)*180/M_PI << endl;
      cout << "##### " << getArgV2(ps[5]-ps[4],ps[4]-Point(0,0))*180/M_PI << endl;
      sort(ps,ps+n,cmp);



      bool f = true;
      double L = 0;
      rep(_,n)
	{
	  if(_ == 0)
	    {
	      L += sqrt(norm(ps[0]-cur1));
	      cur1 = ps[0];
	      used[0] = true;
	      //cout << "L = " << L << endl;
	      continue;
	    }
	  double minArg = inf;
	  double minDist = inf;
	  int minpos = -inf;
	  rep(i,n)
	    {
	      if(used[i])continue;

	      //cout << "cur1(" << cur1.x << "," << cur1.y << ")" << endl;
	      //cout << "cur2(" << cur2.x << "," << cur2.y << ")" << endl;
	      //cout << "ps["<<i<<"](" << ps[i].x << "," << ps[i].y << ")" << endl;

	      double arg = getArgV2(cur1-cur2,ps[i]-cur1);

	      if(f)
		{
		  f = false;
		  minpos = i;
		  minArg = arg;
		  continue;
		}

	      //cout << arg << " ::: " << endl;
	      if(!equals(arg,minArg) && arg < minArg)
		{
		  minpos = i;
		  minArg = arg;
		  minDist = sqrt(norm(cur1-ps[i]));
		}
	      if(equals(arg,minArg) && sqrt(norm(cur1-ps[minpos])) > sqrt(norm(cur1-ps[i])))
		{
		  minDist = sqrt(norm(cur1-ps[i]));
		  minpos = i;
		
		}

	    }
	  //cout << "cur1 (" << cur1.x << "," << cur1.y << ")" << endl;
	  //cout << "phase #" << _ << " " << minpos << "(" << ps[minpos].x << "," << ps[minpos].y << ")" << endl;
	  //cout << "that arg is " << minArg*180/M_PI << endl;

	  //assert(minpos != -inf);
	  used[minpos] = true;
	  L += sqrt(norm(cur1-ps[minpos]));
	  cur2 = cur1;
	  cur1 = ps[minpos];

	  //cout << "L = " << L << endl << endl;
	}
      //L *= 10.0;
      //L = round(L);
      //L /= 10.0;
      //cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
      printf("%.1f\n",L);
    }
  return 0;
}
*/
/*
#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<cassert>
#include<iomanip>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define all(n) (n).begin(),(n).end()

using namespace std;
double EPS = 1e-9;

bool equals(double a,double b)
{
  return fabs((a)-(b)) < EPS;
}

struct Point
{
  double x,y;
  Point(double x=-inf,double y=-inf):x(x),y(y){}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  bool operator < (const Point &b)const
  {
    if(x != b.x)return x < b.x;
    return y < b.y;
  }
};

Point ps[410];
bool use[410];

double toRad(double agl){ return agl*M_PI/180; }

double getArg(Point a,Point bb)
{

}

double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}

int main()
{
  int n;
  while(cin >> n,n)
    {
      rep(i,n)
	{
	  cin >> ps[i].x >> ps[i].y;
	  use[i] = false;
	}
      sort(ps,ps+n);

      Point cur = Point(0,0);
      Point cur2 = Point(0,0);
      double L = 0;
      rep(_,n)
	{
	  if(!_)
	    {
	      cur = ps[0];
	      use[0] = true;
	      L += sqrt(norm(cur-ps[0]));
	      continue;
	    }
	  cout << "cur " << cur.x << "," << cur.y << endl;
	  cout << "cur2 " << cur2.x << "," << cur2.y << endl;
	  int next = -inf;
	  double maxArg = -inf;

	  rep(i,n)
	    {
	      if(use[i])continue;
	      //cout << "i = "<< i << endl;

	      Point cc = cur - cur2;
	      double arg = atan2(ps[i].y-cc.y,ps[i].x-cc.x);

	      if(!equals(arg,toRad(90)) && arg > toRad(90))arg = toRad(-180)-(toRad(180)-arg);
	      cout << i << " arg = " << arg*180/M_PI << " max : " << maxArg << endl;
	      if(!equals(arg,maxArg) && arg > maxArg)
		{
		  maxArg = arg;
		  next = i;
		}
	      else if(equals(arg,maxArg) &&  norm(ps[next]-cur) > norm(ps[i]-cur) )
		{
		  next = i;
		}
	      //cout << endl;
	    }
	  cout << "next = " << next << " " << ps[next].x << "," << ps[next].y << endl;
	  assert(next != -inf);
	  L += sqrt(pow(cur.x-ps[next].x,2)+pow(cur.y-ps[next].y,2));
	

	  cur2 = cur;
	  cur = ps[next];
	  use[next] = true;
	  cout << endl << endl;
	}

      printf("%.1f\n",L);
    }
  return 0;
}





*/
accuracy: 1
time_ms: 20
memory_kb: 1376
final_rank: 9

code_snippet: /*
#include<iostream>
#include<cstdio>
#include<cmath>
#include<sstream>
#include<algorithm>
#include<cassert>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define F first
#define S second
#define all(n) (n).begin(),(n).end()
#define EPS (1e-8)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a,b) (fabs((a)-(b)) < EPS)
using namespace std;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<vi> vvi;
struct Point
{
  double x,y;
  int index;
  Point(double x=-inf,double y=-inf):x(x),y(y){}
 
  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double p){return Point(x*p,y*p);}
 
  bool operator < (const Point& p)const
  {
    return !equals(x,p.x)?x < p.x:y > p.y;
  }
  bool operator == (const Point &p)const
  {
    return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
  }
};
 
struct Segment
{
  Point p1,p2;
  Segment(Point p1=Point(-inf,-inf),Point p2=Point(-inf,-inf)):p1(p1),p2(p2){}
};
 
typedef vector<Point> Polygon;
typedef Segment Line;
typedef vector<Point> Polygon;
 
double dot(Point a,Point b)
{
  return a.x*b.x+a.y*b.y;
}
 
double cross(Point a,Point b)
{
  return a.x*b.y-a.y*b.x;
}
 
double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}
 
double toRad(double agl)
{
  return agl*M_PI/180.0;
}
 
int ccw(Point p0,Point p1,Point p2)
{
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) <-EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS) return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}
 
 
bool PointEquals(Point a,Point b)
{
  return equals(a.x,b.x) && equals(a.y,b.y);
}
 
double abs(Point a)
{
  return sqrt(norm(a));
}
 
double getDistanceLP(Line s,Point p)
{
  return abs(cross(s.p2-s.p1,p-s.p1))/abs(s.p2-s.p1);
}
 
double getDistanceSP(Segment s,Point p)
{
  if(dot(s.p2-s.p1,p-s.p1) < 0.0)return abs(p-s.p1);
  if(dot(s.p1-s.p2,p-s.p2) < 0.0)return abs(p-s.p2);
  return getDistanceLP(s,p);
}
 
Polygon andrewScan(Polygon s,Point now)
{
  Polygon u,l;
  if(s.size() < 3)return s;
  sort(all(s));
 
  u.push_back(s[0]);
  u.push_back(s[1]);
  l.push_back(s[s.size()-1]);
  l.push_back(s[s.size()-2]);
 
  REP(i,2,s.size())
    {
      for(int n=u.size();n>=2 && ccw(u[n-2],u[n-1],s[i]) != CLOCKWISE;n--)
    {
      u.pop_back();
    }
      u.push_back(s[i]);
    }
 
  for(int i=s.size()-3;i>=0;i--)
    {
      for(int n=l.size();n>=2 && ccw(l[n-2],l[n-1],s[i]) != CLOCKWISE;n--)
    {
      l.pop_back();
    }
      l.push_back(s[i]);
    }
 
  reverse(l.begin(),l.end());
  for(int i=u.size()-2;i>=1;i--)l.push_back(u[i]);
  reverse(l.begin(),l.end());
 

  vector<Point> ret;
 
  bool f = false;
  rep(i,l.size())
    {
      if(l[i].index == now.index)f = true;
      if(f == false)continue;
      ret.push_back(l[i]);
      rep(j,s.size())
    {
      if(s[j].index == l[i].index || s[j].index == l[(i+1)%l.size()].index)continue;
      if(getDistanceSP(Segment(l[i],l[(i+1)%l.size()]),s[j]) == ON_SEGMENT)ret.push_back(s[j]);
    }
    }
 
  rep(i,l.size())
    {
      if(l[i].index == now.index)f = false;
      if(f == false)break;
      ret.push_back(l[i]);
 
      rep(j,s.size())
    {
      if(s[j].index == l[i].index || s[j].index == l[(i+1)%l.size()].index)continue;
      if(getDistanceSP(Segment(l[i],l[(i+1)%l.size()]),s[j]) == ON_SEGMENT)ret.push_back(s[j]);
    }
 
    }
 
 
  return ret;
}

vector<Point> convex_hull(vector<Point> ps) {
  int n = ps.size(), k = 0;
  sort(ps.begin(), ps.end());
  vector<Point> ch(2*n);
  for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
    while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--]) // upper-hull
    while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  ch.resize(k-1);
  return ch;
} 

 
int n;
vector<Point> input;
 
void inputt()
{
  input.clear();
  input.resize(n);
  rep(i,n)
    {
      cin >> input[i].x >> input[i].y;
      input[i].index = i; 
    }
}
  
void solve()
{
  bool used[n];
  rep(i,n)used[i] = false;
  double L = 0;
  Point cur = Point(0,0); 
  cur.index = -1; 

  rep(_,n)
    {
      vector<Point> toConvex;
      rep(i,n)
	{
	  if(used[i])continue;
	  toConvex.push_back(input[i]);
	}
      toConvex.push_back(cur);

      toConvex = convex_hull(toConvex);
      reverse(toConvex.begin(),toConvex.end());

      vector<Point> tmp;
      rep(j,toConvex.size())
	{
	  tmp.push_back(toConvex[j]);
	  rep(i,n)
	    {
	      if(used[i])continue;
	      if(toConvex[j].index == input[i].index || toConvex[(j+1)%toConvex.size()].index == input[i].index)continue;
	      if(equals(getDistanceSP(Segment(toConvex[j],toConvex[(j+1)%toConvex.size()]),input[i]),0))
		{
		  tmp.push_back(input[i]);
		}
	    }
	}
      toConvex = tmp;

      
      cout << "toConvex----- cur : " << cur.x << "," << cur.y << endl;
      rep(i,toConvex.size())
      {
	  cout << toConvex[i].x << "," << toConvex[i].y  << " " << toConvex[i].index<< endl;
	}
      cout << endl;
      

      int next = -inf;
      rep(i,toConvex.size())
	{
	  if(toConvex[i].index == cur.index)
	    {
	      next = toConvex[(i+1)%toConvex.size()].index;
	      break;
	    }
	}
      
      assert(next != -inf);
      cout << "next = " << next << " : " << input[next].x << "," << input[next].y << endl;
      used[next] = true;
      L += sqrt(norm(cur-input[next]));
      cur = input[next];

    }

  L *= 10.0;
  L = round(L);
  L /= 10.0;
  cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
}
 
int main()
{
  while(cin >> n,n)
    {
      inputt();

      solve();
 
    }
  return 0;
}

//変数に一旦いれてたらばぐった

*/

#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<cassert>
#include<iomanip>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1 
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define all(n) (n).begin(),(n).end()
#define pow2(a) (a)*(a)
using namespace std;
double EPS = 1e-9;

bool equals(double a,double b)
{
  return fabs((a)-(b)) < EPS;
}

class Point
{
  public:
  int x,y;

  Point(int x = -1,int y = -1): x(x),y(y){}

  Point operator + (Point p ){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (int a){return Point(a*x,a*y);}
  Point operator / (int a){return Point(x/a,y/a);}//※イケメンに限る

  bool operator < (const Point& p) const
  {
    return x != p.x?x<p.x:y<p.y;
  }

};

struct Segment
{
  Point p1,p2;
  Segment(Point p1 = Point(-1,-1),Point p2 = Point(-1,-1)):p1(p1),p2(p2){}
};
typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;


double dot(Point a,Point b)
{
  return a.x*b.x + a.y*b.y;
}

double cross(Point a,Point b)
{
  return a.x*b.y - a.y*b.x;
}

double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}

double getArgV2(Point A,Point B)
{
  return acos(dot(A,B)/(sqrt(norm(A))*sqrt(norm(B))));
  double a = sqrt(norm(A));
  double b = sqrt(norm(B));
  return acos(dot(A,B)/(a*b));
}

bool cmp(const Point &a,const Point &b)
{
  if(a.x != b.x)return a.x < b.x;
  return a.y < b.y;
}

Point ps[1000];
bool used[1000];

int main()
{
 
  int n;
  while(cin >> n,n)
    {
      rep(i,n)cin >> ps[i].x >> ps[i].y;
      Point cur(0,0);
      Point cur2(0,-512);
      double L = 0;
      int last = n;

      rep(_,n)
	{
	  /*
	  cout << "remain"<<endl;
	  rep(i,last)
	    {
	      cout << ps[i].x << "," << ps[i].y << endl;
	    }
	  cout << endl;
	  */
	  int next = 0;
	  REP(i,1,last)
	    {
	      if(equals(atan2(ps[next].y-cur.y,ps[next].x-cur.x),atan2(ps[i].y-cur.y,ps[i].x-cur.x)))
		{
		  if(pow2(cur.x-ps[next].x)+pow2(cur.y-ps[next].y) > pow2(cur.x-ps[i].x)+pow2(cur.y-ps[i].y))
		    {
		      next = i;
		    }
		}
	      else if(getArgV2(cur-cur2,ps[next]-cur) > getArgV2(cur-cur2,ps[i]-cur))
		{
		  next = i;
		}
	    }
	  //cout << "erase : " << ps[next].x << "," << ps[next].y << endl;
	  L += sqrt(pow2(cur.x-ps[next].x)+pow2(cur.y-ps[next].y));
	  cur2 = cur;
	  cur = ps[next];
	  ps[next] = ps[last-1];
	  last--;
	}
      //L *= 10;
      //L = round(L);
      //L /= 10.0;
      printf("%.1f\n",L);
    }
  return 0;
}


/*
int main()
{
  Point A = Point(0,10);
  Point B = Point(-10,15);

  cout << atan2(B.y-A.y,B.x-A.x)*180/M_PI << endl;
  B = Point(11,20);
  cout << atan2(B.y-A.y,B.x-A.x)*180/M_PI << endl;


  int n; 
  while(cin >> n,n)
    {
   

      Point cur1 = Point(0,0);
      Point cur2 = Point(0,0);

      rep(i,n)
	{
	  cin >> ps[i].x >> ps[i].y;
	  cout << i << " :: " << ps[i].x << "," << ps[i].y << endl;
	  used[i] = false;
	}
      cout << atan2(ps[5].y-ps[4].y,ps[5].x-ps[4].x)*180/M_PI << endl;
      cout << "##### " << getArgV2(ps[5]-ps[4],ps[4]-Point(0,0))*180/M_PI << endl;
      sort(ps,ps+n,cmp);



      bool f = true;
      double L = 0;
      rep(_,n)
	{
	  if(_ == 0)
	    {
	      L += sqrt(norm(ps[0]-cur1));
	      cur1 = ps[0];
	      used[0] = true;
	      //cout << "L = " << L << endl;
	      continue;
	    }
	  double minArg = inf;
	  double minDist = inf;
	  int minpos = -inf;
	  rep(i,n)
	    {
	      if(used[i])continue;

	      //cout << "cur1(" << cur1.x << "," << cur1.y << ")" << endl;
	      //cout << "cur2(" << cur2.x << "," << cur2.y << ")" << endl;
	      //cout << "ps["<<i<<"](" << ps[i].x << "," << ps[i].y << ")" << endl;

	      double arg = getArgV2(cur1-cur2,ps[i]-cur1);

	      if(f)
		{
		  f = false;
		  minpos = i;
		  minArg = arg;
		  continue;
		}

	      //cout << arg << " ::: " << endl;
	      if(!equals(arg,minArg) && arg < minArg)
		{
		  minpos = i;
		  minArg = arg;
		  minDist = sqrt(norm(cur1-ps[i]));
		}
	      if(equals(arg,minArg) && sqrt(norm(cur1-ps[minpos])) > sqrt(norm(cur1-ps[i])))
		{
		  minDist = sqrt(norm(cur1-ps[i]));
		  minpos = i;
		
		}

	    }
	  //cout << "cur1 (" << cur1.x << "," << cur1.y << ")" << endl;
	  //cout << "phase #" << _ << " " << minpos << "(" << ps[minpos].x << "," << ps[minpos].y << ")" << endl;
	  //cout << "that arg is " << minArg*180/M_PI << endl;

	  //assert(minpos != -inf);
	  used[minpos] = true;
	  L += sqrt(norm(cur1-ps[minpos]));
	  cur2 = cur1;
	  cur1 = ps[minpos];

	  //cout << "L = " << L << endl << endl;
	}
      //L *= 10.0;
      //L = round(L);
      //L /= 10.0;
      //cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
      printf("%.1f\n",L);
    }
  return 0;
}
*/
/*
#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<cassert>
#include<iomanip>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define all(n) (n).begin(),(n).end()

using namespace std;
double EPS = 1e-9;

bool equals(double a,double b)
{
  return fabs((a)-(b)) < EPS;
}

struct Point
{
  double x,y;
  Point(double x=-inf,double y=-inf):x(x),y(y){}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  bool operator < (const Point &b)const
  {
    if(x != b.x)return x < b.x;
    return y < b.y;
  }
};

Point ps[410];
bool use[410];

double toRad(double agl){ return agl*M_PI/180; }

double getArg(Point a,Point bb)
{

}

double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}

int main()
{
  int n;
  while(cin >> n,n)
    {
      rep(i,n)
	{
	  cin >> ps[i].x >> ps[i].y;
	  use[i] = false;
	}
      sort(ps,ps+n);

      Point cur = Point(0,0);
      Point cur2 = Point(0,0);
      double L = 0;
      rep(_,n)
	{
	  if(!_)
	    {
	      cur = ps[0];
	      use[0] = true;
	      L += sqrt(norm(cur-ps[0]));
	      continue;
	    }
	  cout << "cur " << cur.x << "," << cur.y << endl;
	  cout << "cur2 " << cur2.x << "," << cur2.y << endl;
	  int next = -inf;
	  double maxArg = -inf;

	  rep(i,n)
	    {
	      if(use[i])continue;
	      //cout << "i = "<< i << endl;

	      Point cc = cur - cur2;
	      double arg = atan2(ps[i].y-cc.y,ps[i].x-cc.x);

	      if(!equals(arg,toRad(90)) && arg > toRad(90))arg = toRad(-180)-(toRad(180)-arg);
	      cout << i << " arg = " << arg*180/M_PI << " max : " << maxArg << endl;
	      if(!equals(arg,maxArg) && arg > maxArg)
		{
		  maxArg = arg;
		  next = i;
		}
	      else if(equals(arg,maxArg) &&  norm(ps[next]-cur) > norm(ps[i]-cur) )
		{
		  next = i;
		}
	      //cout << endl;
	    }
	  cout << "next = " << next << " " << ps[next].x << "," << ps[next].y << endl;
	  assert(next != -inf);
	  L += sqrt(pow(cur.x-ps[next].x,2)+pow(cur.y-ps[next].y,2));
	

	  cur2 = cur;
	  cur = ps[next];
	  use[next] = true;
	  cout << endl << endl;
	}

      printf("%.1f\n",L);
    }
  return 0;
}





*/
accuracy: 1
time_ms: 20
memory_kb: 1328
final_rank: 5

code_snippet: /*
#include<iostream>
#include<cstdio>
#include<cmath>
#include<sstream>
#include<algorithm>
#include<cassert>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define F first
#define S second
#define all(n) (n).begin(),(n).end()
#define EPS (1e-8)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a,b) (fabs((a)-(b)) < EPS)
using namespace std;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<vi> vvi;
struct Point
{
  double x,y;
  int index;
  Point(double x=-inf,double y=-inf):x(x),y(y){}
 
  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double p){return Point(x*p,y*p);}
 
  bool operator < (const Point& p)const
  {
    return !equals(x,p.x)?x < p.x:y > p.y;
  }
  bool operator == (const Point &p)const
  {
    return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
  }
};
 
struct Segment
{
  Point p1,p2;
  Segment(Point p1=Point(-inf,-inf),Point p2=Point(-inf,-inf)):p1(p1),p2(p2){}
};
 
typedef vector<Point> Polygon;
typedef Segment Line;
typedef vector<Point> Polygon;
 
double dot(Point a,Point b)
{
  return a.x*b.x+a.y*b.y;
}
 
double cross(Point a,Point b)
{
  return a.x*b.y-a.y*b.x;
}
 
double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}
 
double toRad(double agl)
{
  return agl*M_PI/180.0;
}
 
int ccw(Point p0,Point p1,Point p2)
{
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) <-EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS) return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}
 
 
bool PointEquals(Point a,Point b)
{
  return equals(a.x,b.x) && equals(a.y,b.y);
}
 
double abs(Point a)
{
  return sqrt(norm(a));
}
 
double getDistanceLP(Line s,Point p)
{
  return abs(cross(s.p2-s.p1,p-s.p1))/abs(s.p2-s.p1);
}
 
double getDistanceSP(Segment s,Point p)
{
  if(dot(s.p2-s.p1,p-s.p1) < 0.0)return abs(p-s.p1);
  if(dot(s.p1-s.p2,p-s.p2) < 0.0)return abs(p-s.p2);
  return getDistanceLP(s,p);
}
 
Polygon andrewScan(Polygon s,Point now)
{
  Polygon u,l;
  if(s.size() < 3)return s;
  sort(all(s));
 
  u.push_back(s[0]);
  u.push_back(s[1]);
  l.push_back(s[s.size()-1]);
  l.push_back(s[s.size()-2]);
 
  REP(i,2,s.size())
    {
      for(int n=u.size();n>=2 && ccw(u[n-2],u[n-1],s[i]) != CLOCKWISE;n--)
    {
      u.pop_back();
    }
      u.push_back(s[i]);
    }
 
  for(int i=s.size()-3;i>=0;i--)
    {
      for(int n=l.size();n>=2 && ccw(l[n-2],l[n-1],s[i]) != CLOCKWISE;n--)
    {
      l.pop_back();
    }
      l.push_back(s[i]);
    }
 
  reverse(l.begin(),l.end());
  for(int i=u.size()-2;i>=1;i--)l.push_back(u[i]);
  reverse(l.begin(),l.end());
 

  vector<Point> ret;
 
  bool f = false;
  rep(i,l.size())
    {
      if(l[i].index == now.index)f = true;
      if(f == false)continue;
      ret.push_back(l[i]);
      rep(j,s.size())
    {
      if(s[j].index == l[i].index || s[j].index == l[(i+1)%l.size()].index)continue;
      if(getDistanceSP(Segment(l[i],l[(i+1)%l.size()]),s[j]) == ON_SEGMENT)ret.push_back(s[j]);
    }
    }
 
  rep(i,l.size())
    {
      if(l[i].index == now.index)f = false;
      if(f == false)break;
      ret.push_back(l[i]);
 
      rep(j,s.size())
    {
      if(s[j].index == l[i].index || s[j].index == l[(i+1)%l.size()].index)continue;
      if(getDistanceSP(Segment(l[i],l[(i+1)%l.size()]),s[j]) == ON_SEGMENT)ret.push_back(s[j]);
    }
 
    }
 
 
  return ret;
}

vector<Point> convex_hull(vector<Point> ps) {
  int n = ps.size(), k = 0;
  sort(ps.begin(), ps.end());
  vector<Point> ch(2*n);
  for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
    while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--]) // upper-hull
    while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  ch.resize(k-1);
  return ch;
} 

 
int n;
vector<Point> input;
 
void inputt()
{
  input.clear();
  input.resize(n);
  rep(i,n)
    {
      cin >> input[i].x >> input[i].y;
      input[i].index = i; 
    }
}
  
void solve()
{
  bool used[n];
  rep(i,n)used[i] = false;
  double L = 0;
  Point cur = Point(0,0); 
  cur.index = -1; 

  rep(_,n)
    {
      vector<Point> toConvex;
      rep(i,n)
	{
	  if(used[i])continue;
	  toConvex.push_back(input[i]);
	}
      toConvex.push_back(cur);

      toConvex = convex_hull(toConvex);
      reverse(toConvex.begin(),toConvex.end());

      vector<Point> tmp;
      rep(j,toConvex.size())
	{
	  tmp.push_back(toConvex[j]);
	  rep(i,n)
	    {
	      if(used[i])continue;
	      if(toConvex[j].index == input[i].index || toConvex[(j+1)%toConvex.size()].index == input[i].index)continue;
	      if(equals(getDistanceSP(Segment(toConvex[j],toConvex[(j+1)%toConvex.size()]),input[i]),0))
		{
		  tmp.push_back(input[i]);
		}
	    }
	}
      toConvex = tmp;

      
      cout << "toConvex----- cur : " << cur.x << "," << cur.y << endl;
      rep(i,toConvex.size())
      {
	  cout << toConvex[i].x << "," << toConvex[i].y  << " " << toConvex[i].index<< endl;
	}
      cout << endl;
      

      int next = -inf;
      rep(i,toConvex.size())
	{
	  if(toConvex[i].index == cur.index)
	    {
	      next = toConvex[(i+1)%toConvex.size()].index;
	      break;
	    }
	}
      
      assert(next != -inf);
      cout << "next = " << next << " : " << input[next].x << "," << input[next].y << endl;
      used[next] = true;
      L += sqrt(norm(cur-input[next]));
      cur = input[next];

    }

  L *= 10.0;
  L = round(L);
  L /= 10.0;
  cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
}
 
int main()
{
  while(cin >> n,n)
    {
      inputt();

      solve();
 
    }
  return 0;
}

//変数に一旦いれてたらばぐった

*/

#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<cassert>
#include<iomanip>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1 
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define all(n) (n).begin(),(n).end()
#define pow2(a) (a)*(a)
using namespace std;
double EPS = 1e-9;

bool equals(double a,double b)
{
  return fabs((a)-(b)) < EPS;
}

class Point
{
  public:
  int x,y;

  Point(int x = -1,int y = -1): x(x),y(y){}

  Point operator + (Point p ){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (int a){return Point(a*x,a*y);}
  Point operator / (int a){return Point(x/a,y/a);}//※イケメンに限る

  bool operator < (const Point& p) const
  {
    return x != p.x?x<p.x:y<p.y;
  }

};

struct Segment
{
  Point p1,p2;
  Segment(Point p1 = Point(-1,-1),Point p2 = Point(-1,-1)):p1(p1),p2(p2){}
};
typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;


double dot(Point a,Point b)
{
  return a.x*b.x + a.y*b.y;
}

double cross(Point a,Point b)
{
  return a.x*b.y - a.y*b.x;
}

double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}

double getArgV2(Point A,Point B)
{
  return acos(dot(A,B)/(sqrt(norm(A))*sqrt(norm(B))));
  double a = sqrt(norm(A));
  double b = sqrt(norm(B));
  return acos(dot(A,B)/(a*b));
}

bool cmp(const Point &a,const Point &b)
{
  if(a.x != b.x)return a.x < b.x;
  return a.y < b.y;
}

Point ps[1000];
bool used[1000];

int main()
{
 
  int n;
  while(cin >> n,n)
    {
      rep(i,n)cin >> ps[i].x >> ps[i].y;
      Point cur(0,0);
      Point cur2(0,-512);
      double L = 0;
      int last = n;

      rep(_,n)
	{
	  /*
	  cout << "remain"<<endl;
	  rep(i,last)
	    {
	      cout << ps[i].x << "," << ps[i].y << endl;
	    }
	  cout << endl;
	  */
	  int next = 0;
	  REP(i,1,last)
	    {
	      if(equals(atan2(ps[next].y-cur.y,ps[next].x-cur.x),atan2(ps[i].y-cur.y,ps[i].x-cur.x)))
		{
		  if(pow2(cur.x-ps[next].x)+pow2(cur.y-ps[next].y) > pow2(cur.x-ps[i].x)+pow2(cur.y-ps[i].y))
		    {
		      next = i;
		    }
		}
	      else if(getArgV2(cur-cur2,ps[next]-cur) > getArgV2(cur-cur2,ps[i]-cur))
		{
		  next = i;
		}
	    }
	  //cout << "erase : " << ps[next].x << "," << ps[next].y << endl;
	  L += sqrt(pow2(cur.x-ps[next].x)+pow2(cur.y-ps[next].y));
	  cur2 = cur;
	  cur = ps[next];
	  ps[next] = ps[last-1];
	  last--;
	}

      printf("%.1f\n",L);
    }
  return 0;
}


/*
int main()
{
  Point A = Point(0,10);
  Point B = Point(-10,15);

  cout << atan2(B.y-A.y,B.x-A.x)*180/M_PI << endl;
  B = Point(11,20);
  cout << atan2(B.y-A.y,B.x-A.x)*180/M_PI << endl;


  int n; 
  while(cin >> n,n)
    {
   

      Point cur1 = Point(0,0);
      Point cur2 = Point(0,0);

      rep(i,n)
	{
	  cin >> ps[i].x >> ps[i].y;
	  cout << i << " :: " << ps[i].x << "," << ps[i].y << endl;
	  used[i] = false;
	}
      cout << atan2(ps[5].y-ps[4].y,ps[5].x-ps[4].x)*180/M_PI << endl;
      cout << "##### " << getArgV2(ps[5]-ps[4],ps[4]-Point(0,0))*180/M_PI << endl;
      sort(ps,ps+n,cmp);



      bool f = true;
      double L = 0;
      rep(_,n)
	{
	  if(_ == 0)
	    {
	      L += sqrt(norm(ps[0]-cur1));
	      cur1 = ps[0];
	      used[0] = true;
	      //cout << "L = " << L << endl;
	      continue;
	    }
	  double minArg = inf;
	  double minDist = inf;
	  int minpos = -inf;
	  rep(i,n)
	    {
	      if(used[i])continue;

	      //cout << "cur1(" << cur1.x << "," << cur1.y << ")" << endl;
	      //cout << "cur2(" << cur2.x << "," << cur2.y << ")" << endl;
	      //cout << "ps["<<i<<"](" << ps[i].x << "," << ps[i].y << ")" << endl;

	      double arg = getArgV2(cur1-cur2,ps[i]-cur1);

	      if(f)
		{
		  f = false;
		  minpos = i;
		  minArg = arg;
		  continue;
		}

	      //cout << arg << " ::: " << endl;
	      if(!equals(arg,minArg) && arg < minArg)
		{
		  minpos = i;
		  minArg = arg;
		  minDist = sqrt(norm(cur1-ps[i]));
		}
	      if(equals(arg,minArg) && sqrt(norm(cur1-ps[minpos])) > sqrt(norm(cur1-ps[i])))
		{
		  minDist = sqrt(norm(cur1-ps[i]));
		  minpos = i;
		
		}

	    }
	  //cout << "cur1 (" << cur1.x << "," << cur1.y << ")" << endl;
	  //cout << "phase #" << _ << " " << minpos << "(" << ps[minpos].x << "," << ps[minpos].y << ")" << endl;
	  //cout << "that arg is " << minArg*180/M_PI << endl;

	  //assert(minpos != -inf);
	  used[minpos] = true;
	  L += sqrt(norm(cur1-ps[minpos]));
	  cur2 = cur1;
	  cur1 = ps[minpos];

	  //cout << "L = " << L << endl << endl;
	}
      //L *= 10.0;
      //L = round(L);
      //L /= 10.0;
      //cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
      printf("%.1f\n",L);
    }
  return 0;
}
*/
/*
#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<cassert>
#include<iomanip>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define all(n) (n).begin(),(n).end()

using namespace std;
double EPS = 1e-9;

bool equals(double a,double b)
{
  return fabs((a)-(b)) < EPS;
}

struct Point
{
  double x,y;
  Point(double x=-inf,double y=-inf):x(x),y(y){}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  bool operator < (const Point &b)const
  {
    if(x != b.x)return x < b.x;
    return y < b.y;
  }
};

Point ps[410];
bool use[410];

double toRad(double agl){ return agl*M_PI/180; }

double getArg(Point a,Point bb)
{

}

double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}

int main()
{
  int n;
  while(cin >> n,n)
    {
      rep(i,n)
	{
	  cin >> ps[i].x >> ps[i].y;
	  use[i] = false;
	}
      sort(ps,ps+n);

      Point cur = Point(0,0);
      Point cur2 = Point(0,0);
      double L = 0;
      rep(_,n)
	{
	  if(!_)
	    {
	      cur = ps[0];
	      use[0] = true;
	      L += sqrt(norm(cur-ps[0]));
	      continue;
	    }
	  cout << "cur " << cur.x << "," << cur.y << endl;
	  cout << "cur2 " << cur2.x << "," << cur2.y << endl;
	  int next = -inf;
	  double maxArg = -inf;

	  rep(i,n)
	    {
	      if(use[i])continue;
	      //cout << "i = "<< i << endl;

	      Point cc = cur - cur2;
	      double arg = atan2(ps[i].y-cc.y,ps[i].x-cc.x);

	      if(!equals(arg,toRad(90)) && arg > toRad(90))arg = toRad(-180)-(toRad(180)-arg);
	      cout << i << " arg = " << arg*180/M_PI << " max : " << maxArg << endl;
	      if(!equals(arg,maxArg) && arg > maxArg)
		{
		  maxArg = arg;
		  next = i;
		}
	      else if(equals(arg,maxArg) &&  norm(ps[next]-cur) > norm(ps[i]-cur) )
		{
		  next = i;
		}
	      //cout << endl;
	    }
	  cout << "next = " << next << " " << ps[next].x << "," << ps[next].y << endl;
	  assert(next != -inf);
	  L += sqrt(pow(cur.x-ps[next].x,2)+pow(cur.y-ps[next].y,2));
	

	  cur2 = cur;
	  cur = ps[next];
	  use[next] = true;
	  cout << endl << endl;
	}

      printf("%.1f\n",L);
    }
  return 0;
}





*/
accuracy: 1
time_ms: 20
memory_kb: 1328
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <complex>
#include <cstdio>
using namespace std;

const double PI = acos(-1);
const double EPS = 1e-9;
typedef complex<double> P;

double fix(double x){
	while( x >=
		2 * PI ) x -= 2 * PI;
	while( x < EPS ) x += 2 * PI;
	return x;
}
int main(){
	int N;
	while(cin >> N && N){
		double ans = 0;
		vector<P> v;
		vector<bool> done(N);
		
		for(int i = 0 ; i < N ; i++){
			double x,y;
			cin >> x >> y;
			v.push_back(P(x,y));
		}
		double cx = 0 , cy = 0;
		double dir = PI / 2;
		while(count(done.begin(),done.end(),0) ){
			//cout << cx << " " << cy << " " << dir << endl;
			vector< pair<double,int> > next;
			for(int i = 0 ; i < N ; i++){
				if( done[i] ) continue;
				double ang = fix(atan2(v[i].imag()-cy,v[i].real()-cx) - dir);
				next.push_back(make_pair(ang,i));
			}
			sort(next.rbegin(),next.rend());
			int cur = 0;
			for(int i = 1 ; i < next.size() ; i++){
				if( fabs( next[i].first - next[0].first ) > EPS ){
					break;
				}
				if( abs(P(cx,cy)-v[next[i].second]) < abs(P(cx,cy)-v[next[cur].second]) ){
					cur = i;
				}
			}
			
			done[next[cur].second] = true;
			ans += abs(P(cx,cy)-v[next[cur].second]);
			dir = fix(dir += next[cur].first);
			cx = v[next[cur].second].real();
			cy = v[next[cur].second].imag();
			
		}
		
		printf("%.1lf\n",ans);
	}
}
accuracy: 1
time_ms: 10
memory_kb: 1368
final_rank: 7

code_snippet: #include<iostream>
#include<complex>
#include<vector>
#include<cmath>
#include<algorithm>
#include<cstdio>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

#define X real()
#define Y imag()

typedef complex<double> P;

const double EPS = 1e-8;
const double PI = acos(-1);

int sig(double r) {return (r < -EPS) ? -1 : (r > EPS) ? 1: 0;}
bool eq(double a, double b) {return abs(a - b) < EPS;}

namespace std{
  bool operator<(const P &a, const P &b){
    double arg1 = arg(a), arg2 = arg(b);
    if (sig(arg1 - PI) >= 0) arg1 = -PI;
    if (sig(arg2 - PI) >= 0) arg2 = -PI;
    if(!eq(arg1, arg2)) return arg1 < arg2;
    return norm(a) < norm(b);
  }
}

P plr(double theta) {return polar(1., theta);}

int main() {
  int n;
  for (;;) {
    cin >> n;
    if (n == 0) break;
    vector<P> v;
    rep (i, n) {
      int x, y;
      cin >> x >> y;
      v.push_back(P(x, y));
    }
    rep (i, n) {
      v[i] = v[i] * plr(PI / 2);
      v[i].Y *= -1;
    }
    double res = 0;
    rep (i, n) {
      sort(v.begin(), v.end());
      res += abs(v[0]);
      vector<P> vv;
      rep (j, v.size() - 1) {
	vv.push_back((v[j + 1] - v[0]) * plr(-PI - arg(v[0])));
      }
      v = vv;
    }
    printf("%.1lf\n", res);
  }
}
accuracy: 1
time_ms: 90
memory_kb: 996
final_rank: 4

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)n; ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cout<<*i<<" "; cout<<endl; }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
//geo
#include <complex>
typedef complex<double> P;
inline bool equal(double x, double y){
  return abs(x - y) < EPS;
}
inline bool operator == (const P& x, const P& y){
  return equal(x.real(), y.real()) && equal(x.imag(), y.imag());
}
double dot(P x, P y){
  return real(conj(x) * y);
}
double cross(P x, P y){
  return imag(conj(x) * y);
}
int ccw(P a, P b, P c) {
  b -= a; c -= a;
  if (cross(b, c) > 0)   return +1;       // counter clockwise
  if (cross(b, c) < 0)   return -1;       // clockwise
  if (dot(b, c) < 0)     return +2;       // c--a--b on line
  if (norm(b) < norm(c)) return -2;       // a--b--c on line
  return 0;
}
//---
int main(){
  int n;
  while(cin>>n && n ){
    vector<P> points;
    vector<bool> used(n);
    REP(i,n){
      int x,y;
      cin>>x>>y;
      points.push_back(P(x,y));
    }
    P now(0, 0);
    double ans = 0;
    REP(time, n){
      int next = -1;
      REP(i, n)if(!used[i]){
        bool ok = true;
        REP(j, n)if(!used[j] && i != j){
          int cw = ccw(now, points[i], points[j]);
          if(cw == 0 || cw == 1) {
            ok = false;
            break;
          }
          assert(cw != 2);
        }
        if(ok){
          assert(next == -1);
          next = i;
        }
      }
      assert(next != -1);
      used[next] = true;
      ans += abs(points[next] - now);
      now = points[next];
    }
    printf("%.1lf\n", ans);
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)n; ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cout<<*i<<" "; cout<<endl; }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
//geo
#include <complex>
typedef complex<double> P;
inline bool equal(double x, double y){
  return abs(x - y) < EPS;
}
inline bool operator == (const P& x, const P& y){
  return equal(x.real(), y.real()) && equal(x.imag(), y.imag());
}
double dot(P x, P y){
  return real(conj(x) * y);
}
double cross(P x, P y){
  return imag(conj(x) * y);
}
int ccw(P a, P b, P c) {
  b -= a; c -= a;
  if (cross(b, c) > 0)   return +1;       // counter clockwise
  if (cross(b, c) < 0)   return -1;       // clockwise
  if (dot(b, c) < 0)     return +2;       // c--a--b on line
  if (norm(b) < norm(c)) return -2;       // a--b--c on line
  return 0;
}
//---
int main(){
  int n;
  while(cin>>n && n ){
    vector<P> points;
    vector<bool> used(n);
    REP(i,n){
      int x,y;
      cin>>x>>y;
      points.push_back(P(x,y));
    }
    P now(0, 0);
    double ans = 0;
    REP(time, n){
      int next = -1;
      REP(i, n)if(!used[i]){
        bool ok = true;
        REP(j, n)if(!used[j] && i != j){
          int cw = ccw(now, points[i], points[j]);
          if(cw == 0 || cw == 1) {
            ok = false;
          }
          assert(cw != 2);
        }
        if(ok){
          assert(next == -1);
          next = i;
        }
      }
      assert(next != -1);
      used[next] = true;
      ans += abs(points[next] - now);
      now = points[next];
    }
    printf("%.1lf\n", ans);
  }
  return 0;
}
accuracy: 1
time_ms: 550
memory_kb: 984
final_rank: 12

code_snippet: #include<deque>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#include<algorithm>
#include<string>
#include<iostream>
#include<sstream>
#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
int main(){
  int i;
  int n;
  while(cin>>n,n){
    deque<int> a,b;
    for(i=0;i<n;i++){
      int p,q;
      cin>>p>>q;
      a.push_back(p);
      b.push_back(q);
    }
    int x=0,y=0;
    double z=M_PI/2;
    double sm=0;
    while(a.size()){
      int mn=0;
      for(i=1;i<(int)a.size();i++){
	if(0){
	}else if((atan2(b[mn]-y,a[mn]-x)>z?atan2(b[mn]-y,a[mn]-x)-M_PI*2:atan2(b[mn]-y,a[mn]-x))<(atan2(b[i]-y,a[i]-x)>z?atan2(b[i]-y,a[i]-x)-M_PI*2:atan2(b[i]-y,a[i]-x))){
	  mn=i;
	}else if((atan2(b[mn]-y,a[mn]-x)>z?atan2(b[mn]-y,a[mn]-x)-M_PI*2:atan2(b[mn]-y,a[mn]-x))==(atan2(b[i]-y,a[i]-x)>z?atan2(b[i]-y,a[i]-x)-M_PI*2:atan2(b[i]-y,a[i]-x))){
	  if((a[mn]-x)*(a[mn]-x)+(b[mn]-y)*(b[mn]-y)>(a[i]-x)*(a[i]-x)+(b[i]-y)*(b[i]-y))
	    mn=i;
	}
      }
      sm+=sqrt((a[mn]-x)*(a[mn]-x)+(b[mn]-y)*(b[mn]-y));
      z=atan2(b[mn]-y,a[mn]-x);
      x=a[mn];
      y=b[mn];
      a.erase(a.begin()+mn);
      b.erase(b.begin()+mn);
    }
    printf("%.1lf\n",sm);
  }
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 0
final_rank: 3

code_snippet: #include<cstdio>
#include<cstring>
#include<cmath>
#include<complex>
#include<map>
#include<functional>
#include<algorithm>
#define EPS (1e-10)
#define N 400
using namespace std;
typedef complex<double> P;
typedef struct pdp{
	P p;
	double c, d;
} pdp;
bool operator<(const pdp &a, const pdp &b){
	if(abs(a.c - b.c) < EPS){
		return a.d < b.d;
	}
	else{
		return a.c < b.c;
	}
}

double dot(P a, P b){
	return a.real() * b.real() + a.imag() * b.imag();
}
double vcos(P a, P b){
	return dot(a, b) / abs(a) / abs(b);
}
pdp a[N];
int main(){
	for(;;){
		int n;
		double r;
		P cv = P(0, 1), cp = P(0, 0);
		scanf("%d", &n);
		if(n==0)return 0;
		for(int i=0;i<n;++i){
			int x, y;
			scanf("%d%d", &x, &y);
			a[i].p = P(x, y);
		}
		r = 0.0;
		for(int i=n;i>0;--i){
			//printf("%.1lf, %.1lf\n", cp.real(), cp.imag());
			for(int j=0;j<i;++j){
				a[j].c = -vcos(cv, a[j].p-cp);
				a[j].d = abs(a[j].p-cp);
			}
			sort(a, a+i);
			r += a[0].d;
			cv = a[0].p-cp;
			cp = a[0].p;
			a[0] = a[i-1];
		}
		//printf("%.1lf, %.1lf\n", cp.real(), cp.imag());
		printf("%.1lf\n", r);
	}
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1