#include<bits/stdc++.h>
using namespace std;
typedef pair<double, double> Point;
typedef pair<Point, Point> Segment; // (frm, to)
const double eps = 1e-9;

double norm(Point a) {
    return sqrt(a.first * a.first + a.second * a.second);
}
Point normalize(Point vec) {
    double d = norm(vec);
    return d < eps ? vec : Point(vec.first / d, vec.second / d);
}
Point normalize(Point vec, double len) {
    Point a = normalize(vec);
    return Point(a.first * len, a.second * len);
}
Point getvert(Point v) {
    return Point(-v.second, v.first);
}
Point getv(Point frm, Point to) {
    return Point(to.first - frm.first, to.second - frm.second);
}
Point getv(Segment a) {
    return getv(a.first, a.second);
}
double dist(Point a, Point b) {
    return norm(getv(a, b));
}
double getlen(Segment a) {
    return dist(a.first, a.second);
}

double cross(Point v, Point w) {
    return v.first * w.second - v.second * w.first;
}
bool iscross(Segment a, Segment b) {
    return cross(getv(a), getv(a.first, b.first)) * cross(getv(a), getv(a.first, b.second)) < eps && cross(getv(b), getv(b.first, a.first)) * cross(getv(b), getv(b.first, a.second)) < eps;
}

Segment getcrosses(Point a, double ra, Point b, double rb) {
    double c = dist(a, b);
    double d = (c * c + ra * ra - rb * rb) / (2 * c);
    Point p = normalize(getv(a, b), d);
    Point ctr = Point(p.first + a.first, p.second + a.second);
    double h = sqrt(ra * ra - d * d);
    Point pp = normalize(getvert(getv(a, b)), h);
    return Segment(Point(ctr.first + pp.first, ctr.second + pp.second), Point(ctr.first - pp.first, ctr.second - pp.second));
}

int main() {
    while (1) {
        int n;
        cin >> n;
        if (!n) return 0;
        vector<Point> c(n);
        vector<int> r(n);
        vector<Segment> s(n - 1);
        for (int i = 0; i < n; ++i) {
            cin >> c[i].first >> c[i].second >> r[i];
            if (i) s[i - 1] = getcrosses(c[i - 1], r[i - 1], c[i], r[i]);
        }
        vector<Point> p;
        p.push_back(c[0]);
        for (auto i : s) {
            p.push_back(i.first);
            p.push_back(i.second);
        }
        p.push_back(c[n - 1]);
        vector<double> dp(n * 2, 1e9);
        dp[0] = 0;
        for (int i = 1; i < n * 2; ++i) {
            for (int j = 0; j < i; ++j) {
                bool ok = true;
                for (int k = (j + 1) / 2; k < (i - 1) / 2; ++k) {
                    if (!iscross(Segment(p[j], p[i]), s[k])) {
                        ok = false;
                        break;
                    }
                }
                if (ok)
                    dp[i] = min(dp[i], dp[j] + dist(p[j], p[i]));
            }
        }
        printf("%.9lf\n", dp[n * 2 - 1]);
    }
}