#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Point{
	void set(double arg_x,double arg_y){
		x = arg_x;
		y = arg_y;
	}
	bool operator<(const struct Point &arg) const{
		return x < arg.x;
	}
	double x,y;
};

Point point[100];

struct Line{
	Point p1,p2;
	double dist;
};

struct Data{
	Data(int arg_loc1,int arg_loc2,double arg_sum_dist){
		loc1 = arg_loc1;
		loc2 = arg_loc2;
		sum_dist = arg_sum_dist;
	}
	bool operator<(const struct Data &arg) const{
		return sum_dist > arg.sum_dist;
	}
	int loc1,loc2;
	double sum_dist;
};

int N;
map<int,double>MIN_COST,DIST;

Point calc_Cross_Point(double x1,double x2,double x3,double x4,double y1,double y2,double y3,double y4){
	Point ret;
	ret.x = ((x2-x1)*(y3*(x4-x3)+x3*(y3-y4))-(x4-x3)*(y1*(x2-x1)+x1*(y1-y2)))/((y2-y1)*(x4-x3)-(y4-y3)*(x2-x1));
	if(x1 != x2){
		ret.y = ((y2-y1)*ret.x+y1*(x2-x1)+x1*(y1-y2))/(x2-x1);
	}else{
		ret.y = ((y4-y3)*ret.x+y3*(x4-x3)+x3*(y3-y4))/(x4-x3);
	}
	return ret;
}

double calc_dist(Line line){
	return sqrt((line.p1.x-line.p2.x)*(line.p1.x-line.p2.x)+(line.p1.y-line.p2.y)*(line.p1.y-line.p2.y));
}

int getNUM(int a,int b){
	return a*10000+b;
}


void func(){

	MIN_COST.clear();
	DIST.clear();
	vector<int> HEIGHT;

	for(int i = 0; i < N; i++){
		scanf("%lf %lf",&point[i].x,&point[i].y);
		if(point[i].y > 0){
			HEIGHT.push_back(point[i].y);
		}
	}

	sort(HEIGHT.begin(),HEIGHT.end());
	HEIGHT.erase(unique(HEIGHT.begin(),HEIGHT.end()),HEIGHT.end());

	vector<Point> info;

	for(int i = 0; i < N; i++)info.push_back(point[i]);

	Line tmp;
	Point ret;

	for(int i = 0; i < HEIGHT.size(); i++){
		for(int k = 0; k < N-1; k++){
			tmp.p1 = point[k];
			tmp.p2 = point[k+1];

			if(tmp.p1.y > tmp.p2.y){
				swap(tmp.p1,tmp.p2);
			}

			if(HEIGHT[i] > tmp.p1.y && HEIGHT[i] < tmp.p2.y){
				ret = calc_Cross_Point(tmp.p1.x,tmp.p2.x,-10000.0,10000.0,tmp.p1.y,tmp.p2.y,HEIGHT[i],HEIGHT[i]);
				info.push_back(ret);
			}
		}
	}

	sort(info.begin(),info.end());

	N = (int)(info.size()-1);

	double tmp_dist;

	for(int i = 0; i < info.size()-1; i++){
		tmp.p1 = info[i];
		tmp.p2 = info[i+1];
		tmp_dist = calc_dist(tmp);
		DIST[getNUM(i,i+1)] = tmp_dist;
		DIST[getNUM(i+1,i)] = tmp_dist;
	}

	double ans = DBL_MAX;

	MIN_COST[getNUM(0,N)] = 0.0;
	priority_queue<Data> Q;
	Q.push(Data(0,N,0));


	int tmp_num,next_loc_1,next_loc_2;
	double add_dist;

	while(!Q.empty()){

		if(Q.top().loc1 == Q.top().loc2){
			ans = min(ans,Q.top().sum_dist);
			Q.pop();
		}else if(Q.top().loc2 == Q.top().loc1+1 && info[Q.top().loc2].y == info[Q.top().loc1].y){
			ans = min(ans,Q.top().sum_dist+DIST[getNUM(Q.top().loc1,Q.top().loc2)]);
			Q.pop();
		}else if(Q.top().sum_dist > MIN_COST[getNUM(Q.top().loc1,Q.top().loc2)]){
			Q.pop();
		}else{

			for(int i = -1; i <= 1; i += 1){
				if((Q.top().loc1 == 0 && i == -1) || (Q.top().loc1 == N && i == 1))continue;
				for(int k = -1; k <= 1; k += 1){
					if((Q.top().loc2 == 0 && k == -1) || (Q.top().loc2 == N && k == 1))continue;

					if(i == 0 && k == 0)continue;

					next_loc_1 = Q.top().loc1+i;
					next_loc_2 = Q.top().loc2+k;

					if(fabs(info[next_loc_1].y-info[next_loc_2].y) > EPS || next_loc_1 > next_loc_2)continue;

					add_dist = 0.0;
					if(i != 0){
						add_dist += DIST[getNUM(next_loc_1,Q.top().loc1)];
					}

					if(k != 0){
						add_dist += DIST[getNUM(next_loc_2,Q.top().loc2)];
					}

					tmp_num = getNUM(next_loc_1,next_loc_2);
					auto at = MIN_COST.find(tmp_num);

					if(at != MIN_COST.end()){
						if(MIN_COST[tmp_num] > Q.top().sum_dist+add_dist){
							MIN_COST[tmp_num] = Q.top().sum_dist+add_dist;
							Q.push(Data(next_loc_1,next_loc_2,MIN_COST[tmp_num]));
						}
					}else{
						MIN_COST[tmp_num] = Q.top().sum_dist+add_dist;
						Q.push(Data(next_loc_1,next_loc_2,MIN_COST[tmp_num]));
					}
				}
			}
			Q.pop();
		}
	}

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

int main(){

	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}

Measured memory_bytes: 6112