#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
typedef pair< double , P > PP;

double eps=1e-8;
double eq(double a,double b){
  return (-eps<a-b && a-b<eps);
}

int n;
double x[100],y[100];

vector<double> px,py,gy;
map< int , double > d[10000];

bool flg[10000];

double dist(int i){
  double X=px[i+1]-px[i];
  double Y=py[i+1]-py[i];
  return sqrt( X*X + Y*Y );
}

double D(int na,int nb){
  if(d[na].count(nb)==0)return 1e20;
  else return d[na][nb];
}

double dijkstra(){
  int si=0,sj=(int)py.size()-1;
  priority_queue< PP , vector< PP > , greater< PP > > Q;
  Q.push(PP(0,P(si,sj)));
  
  while(!Q.empty()){

    PP pp=Q.top();Q.pop();
    int a=pp.second.first,na;
    int b=pp.second.second,nb;
    double cost=pp.first,ncost;
    if(d[a][b]<cost)continue;
    if(a==b)return cost;
    
    if(a+1<=sj&&eq(py[a],py[a+1])){
      ncost=cost+dist(a);
      na=a+1,nb=b;
      if(ncost < D(na,nb)){
        d[na][nb]=ncost;
        Q.push(PP(ncost,P(na,nb)));
      }
    }
    
    if(0<=a-1&&py[a-1]==py[a]){
      ncost=cost+dist(a-1);
      na=a-1,nb=b;
      if(ncost < D(na,nb)){
        d[na][nb]=ncost;
        Q.push(PP(ncost,P(na,nb)));
      }
    }
    
    if(0<=b-1&&eq(py[b-1],py[b])){
      ncost=cost+dist(b-1);
      na=a,nb=b-1;
      if(ncost < D(na,nb)){
        d[na][nb]=ncost;
        Q.push(PP(ncost,P(na,nb)));
      }
    }
    
    if(b+1<=sj&&py[b]==py[b+1]){
      ncost=cost+dist(b);
      na=a,nb=b+1;
      if(ncost < D(na,nb)){
        d[na][nb]=ncost;
        Q.push(PP(ncost,P(na,nb)));
      }
    }
    // + +
    na=a,nb=b,ncost=cost;
    while(na+1<=sj&&nb+1<=sj&& eq(py[na+1],py[nb+1]) &&na+1<=nb+1){
      na++,nb++;ncost+=dist(na-1)+dist(nb-1);
      if(flg[na]||flg[nb])break;
    }
    if(ncost < D(na,nb)){
      d[na][nb]=ncost;
      Q.push(PP(ncost,P(na,nb)));
    }

    // + -
    na=a,nb=b,ncost=cost;    
    while(na+1<=sj&&0<=nb-1&& eq(py[na+1],py[nb-1]) &&na+1<=nb-1){
      na++,nb--;ncost+=dist(na-1)+dist(nb);
      if(flg[na]||flg[nb])break;
    }
    if(ncost < D(na,nb)){
      d[na][nb]=ncost;
      Q.push(PP(ncost,P(na,nb)));
    }

    // - +
    na=a,nb=b,ncost=cost;
    while(0<=na-1&&nb+1<=sj&& eq(py[na-1],py[nb+1]) &&na-1<=nb+1){
      na--,nb++;ncost+=dist(na)+dist(nb-1);
      if(flg[na]||flg[nb])break;
    }
    if(ncost < D(na,nb)){
      d[na][nb]=ncost;
      Q.push(PP(ncost,P(na,nb)));
    }


    // - -
    na=a,nb=b,ncost=cost;
    while(0<=na-1&&0<=nb-1&& eq(py[na-1],py[nb-1]) &&na-1<=nb-1){
      na--,nb--;ncost+=dist(na)+dist(nb);
      if(flg[na]||flg[nb])break;
    }
    if(ncost < D(na,nb)){
      d[na][nb]=ncost;
      Q.push(PP(ncost,P(na,nb)));
    }
    
  }
  assert(0);
  return 1e9;
}

void init(){
  px.clear();py.clear();gy.clear();
  memset(flg,0,sizeof(flg));
  for(int i=0;i<10000;i++)d[i].clear();
}

int main(){
  while(1){
    cin>>n;
    if(n==0)break;
    init();
    for(int i=0;i<n;i++){
      cin>>x[i]>>y[i];
      gy.push_back(y[i]);
    }
    sort(gy.begin(),gy.end());
    gy.erase( unique(gy.begin(),gy.end()) , gy.end());
    px.push_back(x[0]);
    py.push_back(y[0]);
    int size=gy.size();
    
    for(int i=1;i<n;i++){
      double vx=x[i]-x[i-1];
      double vy=y[i]-y[i-1];
      
      for(int J=0;J<size;J++){
        int j=(vy>0?J:size-1-J);

        double h=gy[j];
        if(h<=y[i] && h<=y[i-1])continue;
        if(h>=y[i] && h>=y[i-1])continue;
        double dy=h-y[i-1];
        px.push_back(x[i-1]+vx*(dy/vy));
        py.push_back(h);
      }
      flg[px.size()]=true;
      px.push_back(x[i]);
      py.push_back(y[i]);
    }
    flg[0]=true;
    printf("%.10f\n",dijkstra());
  }
  return 0;
}

Measured memory_bytes: 2064