#include <bits/stdc++.h>
 
#define _overload(_1,_2,_3,name,...) name
#define _rep(i,n) _range(i,0,n)
#define _range(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define rep(...) _overload(__VA_ARGS__,_range,_rep,)(__VA_ARGS__)
 
#define _rrep(i,n) _rrange(i,n,0)
#define _rrange(i,a,b) for(int i=(int)(a)-1;i>=(int)(b);--i)
#define rrep(...) _overload(__VA_ARGS__,_rrange,_rrep,)(__VA_ARGS__)
 
#define _all(arg) begin(arg),end(arg)
#define uniq(arg) sort(_all(arg)),(arg).erase(unique(_all(arg)),end(arg))
#define getidx(ary,key) lower_bound(_all(ary),key)-begin(ary)
#define clr(a,b) memset((a),(b),sizeof(a))
#define bit(n) (1LL<<(n))
 
// #define DEBUG
 
#ifdef DEBUG
    #define dump(...) fprintf(stderr, __VA_ARGS__)
#else
    #define dump(...)
#endif
 
template<class T>bool chmax(T &a, const T &b) { return (a<b)?(a=b,1):0;}
template<class T>bool chmin(T &a, const T &b) { return (b<a)?(a=b,1):0;}
 
using namespace std;
using ll=long long;
using vi=vector<int>;
using vll=vector<ll>;
 
const double EPS = 1e-10;
const double PI = acos(-1.0);
const ll inf =1LL << 62;
const ll mod=1000000007LL;
const int dx[4]={1,0,-1,0};
const int dy[4]={0,1,0,-1};
 
 
ll extgcd(ll a,ll b,ll& x,ll& y){x=1,y=0;ll g=a;if(b!=0) g=extgcd(b,a%b,y,x),y-=a/b*x;return g;}
ll ADD(const ll &a, const ll &b,const ll &mod) { return (a+b)%mod;}
ll SUB(const ll &a, const ll &b,const ll &mod) { return (a-b+mod)%mod;}
ll MUL(const ll &a, const ll &b,const ll &mod) { return (1LL*a*b)%mod;}
ll DIV(const ll &a, const ll &b,const ll &mod) {ll x,y; extgcd(b,mod,x,y);return MUL(a,(x+mod)%mod,mod);}
 
random_device rd;
mt19937 mt(rd());
uniform_int_distribution<int> dice(1,6);
uniform_real_distribution<double> score(0.0,10.0);

using R = double;
using Node = tuple<R, int>;
using Elem = tuple<R, int, int>;

const int N = 101;

inline R calc_dist(R x1, R y1, R x2, R y2){
    return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
}

int main(void){
    cin.tie(0);
    ios::sync_with_stdio(false);

    for(int n; cin >> n, n;){
        vector<R> xp(n), yp(n);
        rep(i, n) cin >> xp[i] >> yp[i];

        auto calc_x = [&](R y, int i){
            R ret;
            if(yp[i + 1] == yp[i]){
                ret = xp[i];
            }
            else {
                ret = xp[i] + 1.0 * (xp[i + 1] - xp[i]) * (y - yp[i]) / (yp[i + 1] - yp[i]);
            }
            return ret;
        };

        vector<Node> nodes;
        rep(i, n){
            nodes.emplace_back(Node(xp[i], yp[i]));
            if(i == n - 1) break;

            rep(j, n){
                if(min(yp[i], yp[i + 1]) < yp[j] and yp[j] < max(yp[i], yp[i + 1])){
                    nodes.emplace_back(Node(calc_x(yp[j], i), yp[j]));
                }
            }
        }
        sort(_all(nodes));
        nodes.erase(unique(_all(nodes)), end(nodes));
        int m = nodes.size();

        if(n == 6){
            for(auto& e : nodes){
                R x; int y; tie(x, y) = e;
            }
        }

        priority_queue<Elem, vector<Elem>, greater<Elem>> q;
        Elem start = Elem(0.0, 0, m - 1);
        q.push(start);
        map<int, map<int, R>> min_dist; min_dist[0][m - 1] = 0.0;

        R res = 0.0;
        while(q.size()){
            Elem cur = q.top(); q.pop();
            R dist; int a, b; tie(dist, a, b) = cur;
            if(min_dist[a][b] != dist) continue;

            if(a == b){
                res = dist;
                break;
            }

            R xa, xb; int ya, yb;
            tie(xa, ya) = nodes[a];
            tie(xb, yb) = nodes[b];

            rep(na, a - 1, a + 2){
                rep(nb, b - 1, b + 2){
                    if(na < 0 or na >= m or nb < 0 or nb >= m) continue;
                    R nxa, nxb; int nya, nyb;
                    tie(nxa, nya) = nodes[na];
                    tie(nxb, nyb) = nodes[nb];
                    if(nya != nyb) continue;

                    R ndist = dist + calc_dist(xa, ya, nxa, nya) + calc_dist(xb, yb, nxb, nyb);
                    if(min_dist[na].find(nb) == end(min_dist[na]) or ndist < min_dist[na][nb]){
                        min_dist[na][nb] = ndist;
                        q.push(Elem(ndist, na, nb));
                    }
                }
            }
        }

        cout.precision(20);
        cout << fixed << res << endl;
    }

    return 0;
}

Measured memory_bytes: 5244