#include <bits/stdc++.h>
using namespace std;
typedef complex<double> P;

const double eps = 1e-8;

bool equals(double a, double b) {
  return abs(a - b) < eps;
}

bool equals(P a, P b) {
  return equals(a.real(), b.real()) && equals(a.imag(), b.imag());
}

namespace std {
  bool operator < (const P &a, const P &b) {
    if(!equals(a.real(), b.real())) return a.real() < b.real();
    if(!equals(a.imag(), b.imag())) return a.imag() < b.imag();
    return false;
  }
  bool operator == (const P &a, const P &b) {
    return equals(a, b);
  }
  bool operator != (const P &a, const P &b) {
    return !(a == b);
  }
};

double dot(P a, P b) {
  return a.real()*b.real() + a.imag()*b.imag();
}

double cross(P a, P b) {
  return a.real()*b.imag() - a.imag()*b.real();
}

int ccw(P p, P a, P b) {
  a -= p;
  b -= p;
  if(cross(a, b) > eps) return 1;
  if(cross(a, b) < -eps) return -1;
  if(dot(a, b) < -eps) return 2;
  if(norm(b) - norm(a) > eps) return -2;
  return 0;
}

bool isIntersect(P a1, P a2, P b1, P b2) {
  return ( ccw(a1, a2, b1) * ccw(a1, a2, b2) <= 0 &&
	   ccw(b1, b2, a1) * ccw(b1, b2, a2) <= 0 );
}

P getCrossP(P a1, P a2, P b1, P b2) {
  P a = a2 - a1;
  P b = b2 - b1;
  return a1 + a * cross(b, b1 - a1) / cross(b, a);
}

struct State {
  int a, b;
  double cost;
  bool operator < (const State &s) const {
    return cost > s.cost;
  }
};

int main() {
  for(int N; cin >> N && N; ) {
    vector<P> ps(N);
    for(int i = 0; i < N; ++i) {
      cin >> ps[i].real() >> ps[i].imag();
    }
    for(int i = 0; i+1 < N; ++i) {
      for(int j = 0; j < N; ++j) {
	P a = ps[i];
	P b = ps[i+1];
	double y = ps[j].imag();
	if(equals(a.imag(), b.imag())) continue;
	if((a.imag() <= y && y <= b.imag()) || 
	   (b.imag() <= y && y <= a.imag())); else continue;
	P c((a.real()-b.real())*y/(a.imag()-b.imag())
	    -cross(a,b)/(a.imag()-b.imag()), y);
	ps.push_back(c);
      }
    }
    sort(ps.begin(), ps.end());
    ps.erase(unique(ps.begin(), ps.end()), ps.end());
    //for(int i = 0; i < ps.size(); ++i) cout << ps[i] << endl;

    int M = ps.size();
    int to[2][M], isup[2][M];
    double cost[2][M];
    int id[M];
    for(int i = 0, k = 0; i < 2; ++i) {
      for(int j = 0; j < M; ++j) {
	isup[i][j] = --k;
      }
    }
    id[0] = 0;
    for(int i = 1, k = 0; i < M; ++i) {
      if(!equals(ps[i-1].imag(), ps[i].imag())) ++k;
      id[i] = k;
    }
    for(int i = 1, s = 0; i < M; ++i) {
      if(equals(ps[s].imag(), ps[i].imag())) continue;
      double sum = 0.0;
      bool up = (ps[s].imag() < ps[i].imag());
      for(int j = i-1; j >= s; --j) {
	sum += abs(ps[j] - ps[j+1]);
	to[0][j] = i;
	cost[0][j] = sum;
	isup[0][j] = up;
      }
      s = i;
    }
    for(int i = M-2, s = M-1; i >= 0; --i) {
      if(equals(ps[s].imag(), ps[i].imag())) continue;
      double sum = 0.0;
      bool up = (ps[s].imag() < ps[i].imag());
      for(int j = i+1; j <= s; ++j) {
	sum += abs(ps[j] - ps[j-1]);
	to[1][j] = i;
	cost[1][j] = sum;
	isup[1][j] = up;
      }
      s = i;
    }

    const double inf = 1e10;
    double res = inf;
    try {
      priority_queue<State> que;
      map<pair<int,int>, double> C;
      que.push((State){0, M-1, 0});
      C[make_pair(0, M-1)] = 0;
      while(que.size()) {
	const State s = que.top();
	que.pop();
	if(C[make_pair(s.a, s.b)] < s.cost) continue;
	if(s.cost > res) throw 0;
	int a = s.a;
	int b = s.b;
	if(id[a] == id[b]) {
	  res = min(res, s.cost + abs(ps[a] - ps[b]));
	  continue;
	}
	for(int da = 0; da < 2; ++da) {
	  for(int db = 1; db >= 0; --db) {
	    if(isup[da][a] != isup[db][b]) continue;
	    const State t = {to[da][a], to[db][b], 
			     s.cost + cost[da][a] + cost[db][b]};
	    if(C.count(make_pair(t.a, t.b)) &&
	       C[make_pair(t.a, t.b)] <= t.cost) continue;
	    que.push(t);
	    C[make_pair(t.a, t.b)] = t.cost;
	  }
	}
      }
    } catch(...) {};
    printf("%.10f\n", res);
  }
  return 0;
}

Measured memory_bytes: 3408