#include<bits/stdc++.h>
using namespace std;


int N;
int X[101];
int Y[101];

struct State{
	int x1;
	int x2;
	int t; 
	State(int x1, int x2, int t) : x1(x1), x2(x2), t(t) {}

};

bool operator < (const State& a, const State& b){
	if(a.x1 != b.x1) return a.x1 < b.x1;
	if(a.x2 != b.x2) return a.x2 < b.x2;
	else return a.t < b.t;
}


ostream& operator<<(ostream& os, const State& dt){
	os << "(" << dt.x1 << ',' << dt.x2 << ',' << dt.t << ")";
	return os;
}

typedef pair<double, State> P;
set<State> reached;

double distance(double x1, double y1, double x2, double y2){
	double xx = x1 - x2;
	double yy = y1 - y2;
	return sqrt(xx * xx + yy * yy);
}

double distance(int i1, int i2){
	return distance(X[i1], Y[i1], X[i2], Y[i2]);
}

double posX(int idx, int y){
	double ret;
	if(Y[idx] == y) ret = X[idx];
	else{
		double dx = X[idx + 1] - X[idx];
		double dy = Y[idx + 1] - Y[idx];
		ret =  X[idx] + (y - Y[idx]) / (dy / dx);
	}
	if(X[idx] <= ret && ret <= X[idx + 1]){
		return ret;
	}else{
		return -1;
	}


}

double d1(int i1, int i1n, int i2){
	int yc = Y[i1];
	int y1 = Y[i1n];
	int y21 = Y[i2];
	int y22 = Y[i2 + 1];
	if(y21 <= y1 && y1 <= y22 || y22 <= y1 && y1 <= y21){
		double xx = posX(i2, Y[i1]);
		double xx2 = posX(i2, Y[i1n]);
		if(xx < 0 || xx2 < 0) return -1;
		return distance(i1, i1n) + distance(xx, Y[i1], xx2, Y[i1n]);
	}else{
		return -1;
	}
}
double d2(int i1, int i1n, int i2){
	int y11 = Y[i1];
	int y12 = Y[i1n];
	int y2 = Y[i2];
	int mi = min(i1, i1n);
	if(y11 <= y2 && y2 <= y12 || y12 <= y2 && y2 <= y11){
		double xx1 = posX(mi, Y[i2]);
		double xx2 = posX(i2, Y[i1]);
		if(xx1 < 0 || xx2 < 0) return -1;
		return distance(X[i1], Y[i1], xx1, Y[i2]) + distance(xx2, Y[i1], X[i2], Y[i2]);
	}else{
		return -1;
	}
}

double d3(int i1, int i1n, int i2, int i2n){
	int y11 = Y[i1];
	int y12 = Y[i1n];
	int y2 = Y[i2n];
	int mi = min(i1, i1n);
	int mmi = min(i2, i2n);
	if(y11 <= y2 && y2 <= y12 || y12 <= y2 && y2 <= y11){
		double xx1 = posX(mi, Y[i2n]);
		double xx2 = posX(mmi, Y[i1]);
		if(xx1 < 0 || xx2 < 0) return -1;
		return distance(X[i1], Y[i1], xx1,  Y[i2n]) + distance(xx2, Y[i1], X[i2n], Y[i2n]);
	}else{
		return -1;
	}
}

int main(){
	while(cin >> N, N){
		priority_queue< P, vector< P >, greater< P > > que;
		for(int i = 0; i < N; i++){
			cin >> X[i] >> Y[i];
		}
		X[N] = 1e9;
		Y[N] = -1e9;
		reached.clear();
		que.push(P(0.0, State(0, N-1, 0)));
		double ans = 1e9;

		while(!que.empty()){
			P p = que.top(); que.pop();
			if(reached.find(p.second) != reached.end()) continue;
			//cout << "(" << p.second << "," << p.first << ")" << endl;
			State s = p.second;
			reached.insert(s);
			if(s.x1 == s.x2) ans = min(ans, p.first);
			else{
				double nd;
				if(s.t == 0){
					if(s.x1 > 0){
						nd = d1(s.x1, s.x1 - 1, s.x2);
						if(nd >= 0){
							//cout << s << "=>" << State(s.x1 - 1, s.x2, 0) <<   nd <<endl;
							que.push(P(p.first + nd, State(s.x1 - 1, s.x2, 0)));
						}
					}
					if(s.x1 < N - 1){
						nd = d1(s.x1, s.x1 + 1, s.x2);
						if(nd >= 0){
							//cout << s << "=>" << State(s.x1 + 1, s.x2, 0) <<   nd <<endl;
							que.push(P(p.first + nd, State(s.x1 + 1, s.x2, 0)));
						}
					}
					nd = d2(s.x1, s.x1 + 1, s.x2);
					if(nd >= 0){
						//cout << s << "=>" << State(s.x1, s.x2, 1) <<   nd <<endl;
						que.push(P(p.first + nd, State(s.x1, s.x2, 1)));
					}
					if(s.x1 > 0){
						nd = d2(s.x1, s.x1 - 1, s.x2);
						if(nd >= 0){
							//cout << s << "=>" << State(s.x1-1, s.x2, 1) <<   nd <<endl;
							que.push(P(p.first + nd, State(s.x1 - 1, s.x2, 1)));
						}
					}
					if(s.x2 < N - 1 && s.x1 > 0){
						nd = d3(s.x1, s.x1 - 1, s.x2, s.x2 + 1);
						if(nd >= 0){
							//cout << s << "=>" << State(s.x1 - 1, s.x2+1, 0) <<  nd <<endl;
							que.push(P(p.first + nd, State(s.x1 - 1, s.x2 + 1, 1)));
						}
					}
					if(s.x2 < N - 1){	
						nd = d3(s.x1, s.x1 + 1, s.x2, s.x2 + 1);
						if(nd >= 0){
							//cout << s << "=>" << State(s.x1, s.x2+1, 0) <<  nd <<endl;
							que.push(P(p.first + nd, State(s.x1, s.x2+1, 1)));
						}
					}
					
				}else{
					if(s.x2 > 0){
						nd = d1(s.x2, s.x2 - 1, s.x1);
						if(nd >= 0){
							//cout << s << "=>" << State(s.x1, s.x2 -1, 1) <<   nd <<endl;
							que.push(P(p.first + nd, State(s.x1, s.x2 - 1, 1)));
						}
					}
					if(s.x2 < N - 1){
						nd = d1(s.x2, s.x2 + 1, s.x1);
						if(nd >= 0){
							//cout << s << "=>" << State(s.x1, s.x2 +1, 1) <<   nd <<endl;
							que.push(P(p.first + nd, State(s.x1, s.x2 + 1, 1)));
						}
					}
					nd = d2(s.x2, s.x2 + 1, s.x1);
					if(nd >= 0){
						//cout << s << "=>" << State(s.x1, s.x2, 0) <<   nd <<endl;
						que.push(P(p.first + nd, State(s.x1, s.x2, 0)));
					}
					if(s.x2 > 0){
						nd = d2(s.x2, s.x2 - 1, s.x1);
						if(nd >= 0){
							//cout << s << "=>" << State(s.x1, s.x2-1, 0) <<  nd <<endl;
							que.push(P(p.first + nd, State(s.x1, s.x2 - 1, 0)));
						}
					}
					if(s.x1 < N - 1 && s.x2 > 0){
						nd = d3(s.x2, s.x2 - 1, s.x1, s.x1 + 1);
						if(nd >= 0){
							//cout << s << "=>" << State(s.x1 + 1, s.x2-1, 0) <<  nd <<endl;
							que.push(P(p.first + nd, State(s.x1 + 1, s.x2 - 1, 0)));
						}
					}
					if(s.x1 < N - 1){	
						nd = d3(s.x2, s.x2 + 1, s.x1, s.x1 + 1);
						if(nd >= 0){
							//cout << s << "=>" << State(s.x1 + 1, s.x2, 0) <<  nd <<endl;
							que.push(P(p.first + nd, State(s.x1 + 1, s.x2, 0)));
						}
					}
				}
			}
		}

		printf("%.20lf\n", ans);

	}
}

Measured memory_bytes: 4144