#include <map>
#include <cmath>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
struct state {
	int posa, posb; double cost;
};
bool operator<(const state& s1, const state& s2) {
	return s1.cost > s2.cost;
}
int main() {
	int N;
	while (cin >> N, N) {
		vector<int> X(N), Y(N);
		for (int i = 0; i < N; ++i) {
			cin >> X[i] >> Y[i];
		}
		vector<int> cy = Y;
		sort(cy.begin(), cy.end());
		cy.erase(unique(cy.begin(), cy.end()), cy.end());
		vector<pair<double, int> > seq;
		for (int i = 0; i < N - 1; ++i) {
			seq.push_back(make_pair(X[i], Y[i]));
			int ly = min(Y[i], Y[i + 1]), ry = max(Y[i], Y[i + 1]);
			for (int j = 0; j < cy.size(); ++j) {
				if (ly < cy[j] && cy[j] < ry) {
					seq.push_back(make_pair(X[i] + double(X[i + 1] - X[i]) * (cy[j] - Y[i]) / (Y[i + 1] - Y[i]), cy[j]));
				}
			}
		}
		seq.push_back(make_pair(X[N - 1], Y[N - 1]));
		sort(seq.begin(), seq.end());
		vector<int> sy(seq.size()); vector<double> d(seq.size() - 1);
		for (int i = 0; i < seq.size(); ++i) {
			sy[i] = seq[i].second;
			if (i != seq.size() - 1) {
				d[i] = hypot(seq[i + 1].first - seq[i].first, seq[i + 1].second - seq[i].second);
			}
		}
		map<pair<int, int>, double> dist;
		function<double(int, int)> getdist = [&](int pa, int pb) {
			if (dist.find(make_pair(pa, pb)) == dist.end()) return 1.0e+99;
			return dist[make_pair(pa, pb)];
		};
		priority_queue<state> que;
		que.push({ 0, int(sy.size()) - 1, 1.0 });
		dist[make_pair(0, sy.size() - 1)] = 1.0;
		double ans = 1.0e+99;
		while (!que.empty()) {
			state s = que.top(); que.pop();
			double curdist = getdist(s.posa, s.posb);
			if (s.posa == s.posb) {
				ans = curdist - 1.0;
				break;
			}
			if (sy[s.posa + 1] == sy[s.posb] && getdist(s.posa + 1, s.posb) > curdist + d[s.posa]) {
				dist[make_pair(s.posa + 1, s.posb)] = curdist + d[s.posa];
				que.push(state{ s.posa + 1, s.posb, curdist + d[s.posa] });
			}
			if (sy[s.posb - 1] == sy[s.posa] && getdist(s.posa, s.posb - 1) > curdist + d[s.posb - 1]) {
				dist[make_pair(s.posa, s.posb - 1)] = curdist + d[s.posb - 1];
				que.push(state{ s.posa, s.posb - 1, curdist + d[s.posb - 1] });
			}
			if (s.posa != 0 && sy[s.posa - 1] == sy[s.posb] && getdist(s.posa - 1, s.posb) > curdist + d[s.posa - 1]) {
				dist[make_pair(s.posa - 1, s.posb)] = curdist + d[s.posa - 1];
				que.push(state{ s.posa - 1, s.posb, curdist + d[s.posa - 1] });
			}
			if (s.posb != sy.size() - 1 && sy[s.posb + 1] == sy[s.posa] && getdist(s.posa, s.posb + 1) > curdist + d[s.posb]) {
				dist[make_pair(s.posa, s.posb + 1)] = curdist + d[s.posb];
				que.push(state{ s.posa, s.posb + 1, curdist + d[s.posb] });
			}
			if (s.posb - s.posa >= 2 && sy[s.posa + 1] == sy[s.posb - 1] && getdist(s.posa + 1, s.posb - 1) > curdist + d[s.posa] + d[s.posb - 1]) {
				dist[make_pair(s.posa + 1, s.posb - 1)] = curdist + d[s.posa] + d[s.posb - 1];
				que.push(state{ s.posa + 1, s.posb - 1, curdist + d[s.posa] + d[s.posb - 1] });
			}
			if (s.posa != 0 && sy[s.posa - 1] == sy[s.posb - 1] && getdist(s.posa - 1, s.posb - 1) > curdist + d[s.posa - 1] + d[s.posb - 1]) {
				dist[make_pair(s.posa - 1, s.posb - 1)] = curdist + d[s.posa - 1] + d[s.posb - 1];
				que.push(state{ s.posa - 1, s.posb - 1, curdist + d[s.posa - 1] + d[s.posb - 1] });
			}
			if (s.posb != sy.size() - 1 && sy[s.posa + 1] == sy[s.posb + 1] && getdist(s.posa + 1, s.posb + 1) > curdist + d[s.posa] + d[s.posb]) {
				dist[make_pair(s.posa + 1, s.posb + 1)] = curdist + d[s.posa] + d[s.posb];
				que.push(state{ s.posa + 1, s.posb + 1, curdist + d[s.posa] + d[s.posb] });
			}
			if (s.posa != 0 && s.posb != sy.size() - 1 && sy[s.posa - 1] == sy[s.posb + 1] && getdist(s.posa - 1, s.posb + 1) > curdist + d[s.posa - 1] + d[s.posb]) {
				dist[make_pair(s.posa - 1, s.posb + 1)] = curdist + d[s.posa - 1] + d[s.posb];
				que.push(state{ s.posa - 1, s.posb + 1, curdist + d[s.posa - 1] + d[s.posb] });
			}
		}
		cout.precision(15);
		cout << fixed << ans << endl;
	}
	return 0;
}


Measured memory_bytes: 5452