#include <iostream>
#include <algorithm>
#include <cmath>
#include <complex>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const double EPS = 1e-8;
const double INF = 1e12;

typedef complex<double> P;
namespace std {
	bool operator < (const P& a, const P& b) {
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
}
double cross(const P& a, const P& b) {
  return imag(conj(a)*b);
}
double dot(const P& a, const P& b) {
	return real(conj(a)*b);
}

struct L : public vector<P> {
	L(const P &a, const P &b) {
		push_back(a); push_back(b);
	}
};

typedef vector<P> G;

struct C {
	P p; double r;
	C(){ }
	C(const P &p, double r) : p(p), r(r) { }
};

int ccw(P a, P b, P c) {
	b-=a;c-=a;
	if(cross(b, c) > 0)  return +1;// counter clockwise
	if(cross(b, c) < 0)  return -1;// clockwise
	if(dot(b, c) < 0)    return +2;// c--a--b on line
	if(norm(b) < norm(c))return -2;// a--b--c on line
	return 0;
}

bool intersectSS(const L &s, const L &t) {
	return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 && ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0;
}


class State{
public:
	double sum;
	int t,s;
	P cur;
	State(){}
	State(double c, int a, int b, P p):sum(c),t(a),s(b),cur(p){}
	bool operator < (const State &opp)const{
		return sum > opp.sum;
	}
};
P rotate(P t , P p , double r){
	double ta=cos(r)*real(t-p)-sin(r)*imag(t-p)+real(p);
	double tb=sin(r)*real(t-p)+cos(r)*imag(t-p)+imag(p);
	return P(ta , tb);
}


P unit_vector(P t){
	return t/fabs(abs(t));
}

L interpointCC(C a , C b){
	double di=fabs(abs(a.p-b.p));
	if(di > a.r+b.r || di < fabs(a.r-b.r)) return L(P(0, 0), P(0, 0));
	double t=(a.r*a.r-b.r*b.r+di*di)/(di+di);
	double rd=acos(t/a.r);

	P dv=unit_vector(b.p-a.p);
	P g1=rotate(dv , P(0,0) , rd);
	P g2=rotate(dv , P(0,0) , -rd);
	return L(a.p+g1*a.r, a.p+g2*a.r);
}

double dp[101][2];
int v[101][2];
vector <L> Lines;

bool check(L l, int s, int t){
	for(;s<t;s++) if(!intersectSS(l, Lines[s]))return 0;
	return 1;
}

int main(){
	int i,j,n;

	while(cin>>n, n){
		priority_queue<State> S;
		memset(v, 0, sizeof(v));
		for(i=0;i<=100;i++) dp[i][0] = dp[i][1] = INF;
		Lines.clear();
		C Prev, Now;
		double x, y, r;
		cin >> x >> y >> r;
		Now = C(P(x, y), r);
		P Start = Now.p;
		Lines.push_back(L(Start, Start));
		for(i=1;i<n;i++){
			Prev = Now;
			cin >> x >> y >> r;
			Now = C(P(x, y), r);
			Lines.push_back(interpointCC(Now, Prev));
		}
		Lines.push_back(L(Now.p, Now.p));
		S.push(State(0, 0, 0, Start));
		while(!S.empty()){
			State t = S.top();S.pop();
			if(v[t.t][t.s]) continue;
			v[t.t][t.s] = 1;
			if(t.t == n) break;
			for(i=t.t+1;i<=n;i++){
				for(j=0;j<2;j++){
					if(v[i][j]) continue;
					L l = L(t.cur, Lines[i][j]);
					if(!check(l, t.t+1, i)) continue;
					if(dp[i][j] < abs(l[1]-l[0]) + t.sum) continue;
					dp[i][j] = abs(l[1]-l[0]) + t.sum;
					S.push(State(dp[i][j], i, j, l[1]));
				}
			}
		}
		printf("%.4lf\n", dp[n][0]);
	}
}