#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <sstream>
#include <cmath>
#include <set>
#include <iomanip>
#include <deque>
using namespace std;
typedef long long ll;

#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define RREP(i,n) for(int (i)=(int)(n)-1;i>=0;i--)
#define FOREACH(i,Itr) for(auto (i)=(Itr).begin();(i)!=(Itr).end();(i)++)
#define REMOVE(Itr,n) (Itr).erase(remove((Itr).begin(),(Itr).end(),n),(Itr).end())
#define UNIQUE(Itr) sort((Itr).begin(),(Itr).end()); (Itr).erase(unique((Itr).begin(),(Itr).end()),(Itr).end())
#define LBOUND(Itr,val) lower_bound((Itr).begin(),(Itr).end(),(val))
#define UBOUND(Itr,val) upper_bound((Itr).begin(),(Itr).end(),(val))


template <class T> class Dijkstra{
    typedef struct{ int to; T cost; }Edge;
    int V;
    const T INF_T = 1e18+7;
    vector< vector<Edge> > G;
    vector<T> d;
public:
    Dijkstra(int _V) { V=_V+1; G.resize(V); d.resize(V); }
    void add_edge_oneway(int a, int b, T c){
        Edge e; e.to=b; e.cost=c;
        G[a].push_back(e);
    }
    void add_edge_twoway(int a, int b, T c){
        Edge e1,e2; e1.to=b; e1.cost=c; e2.to=a; e2.cost=c;
        G[a].push_back(e1);
        G[b].push_back(e2);
    }
    void init(int s){
        priority_queue< pair<T,int>,vector< pair<T,int> >, greater< pair<T,int> > > que;
        for(int i=0;i<V;i++)d[i]=INF_T;
        d[s]=0;
        que.push(make_pair(0,s));
        while(!que.empty()){
            pair<T,int> p=que.top(); que.pop();
            int v=p.second;
            if(d[v]<p.first)continue;
            for(int i=0;i<G[v].size();i++){
                Edge e=G[v][i];
                if(d[e.to]>d[v]+e.cost){
                    d[e.to]=d[v]+e.cost;
                    que.push(make_pair(d[e.to],e.to));
                }
            }
        }
    }
    T dist(int a){
        return d[a];
    }
};



map< pair<ll,ll>,int > v;

int main(){
    
    ll xs,ys,xt,yt; cin>>xs>>ys>>xt>>yt;
    ll N; cin>>N;
    vector<ll> x(N),y(N),r(N);
    REP(i,N)cin>>x[i]>>y[i]>>r[i];
    
    Dijkstra<double> inst(12000);
    REP(i,N){
        v[make_pair(x[i],y[i])]=i+1;
    }
    
    REP(i,N)REP(j,N){
        if(i!=j){
            int v1=v[make_pair(x[i],y[i])];
            int v2=v[make_pair(x[j],y[j])];
            double dist=sqrt (pow((double)abs(x[i]-x[j]),2.0)+pow((double)abs(y[i]-y[j]),2.0) );
            dist-=(r[i]+r[j]);
            dist=max(dist,0.0);
            inst.add_edge_twoway(v1,v2,dist);
        }
    }
    
    int vs=10000;
    int vt=10001;
    REP(i,N){
        int v1=v[make_pair(x[i],y[i])];
        double dist1=sqrt (pow((double)abs(x[i]-xs),2.0)+pow((double)abs(y[i]-ys),2.0) );
        dist1-=r[i];
        dist1=max(dist1,0.0);
        inst.add_edge_twoway(vs,v1,dist1);
        
        double dist2=sqrt (pow((double)abs(x[i]-xt),2.0)+pow((double)abs(y[i]-yt),2.0) );
        dist2-=r[i];
        dist2=max(dist2,0.0);
        inst.add_edge_twoway(vt,v1,dist2);
    }
    
    double distst=sqrt (pow((double)abs(xs-xt),2.0)+pow((double)abs(ys-yt),2.0) );
    inst.add_edge_twoway(vs,vt,distst);
    
    inst.init(vs);
    cout<<fixed<<setprecision(10)<<inst.dist(vt)<<endl;
    
    return 0;
}





Measured memory_bytes: 37360