#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ull unsigned long long
#define vll vector<ll>
#define pii pair<int, int>
#define vii vector<pii>
#define vs vector<string>
#define vb vector<bool>
#define vi vector<int>
#define vd vector<double>
#define vvi vector< vector<int> >
#define vvii vector< vector< pii > >
#define ld long double
#define mapii map<int, int>
#define mapsi map<string, int>
#define erep(i, x, n) for (auto i = x; i<=(ll)(n); i++)
#define rep(i, x, n) for(auto i = x; i<(ll)(n); i++)
//#define INF  LLONG_MAX
#define all(v) ((v).begin()), ((v).end())
#define sz(v) ((int)((v).size()))
#define pie  acos(-1)
#define mod(n,m) ((n % m + m) % m)
#define eps (1e-8)
#define reset(n, m) memset(n, m, sizeof n)
#define endl '\n'
#define output freopen("output.txt", "w", stdout)
#define mp(x, y, z) {{x, y}, z}


double INF = 1e100;
double EPS = 1e-7;

struct PT
{
    double x, y;
    PT() {}
    PT(double x, double y) : x(x), y(y) {}
    PT(const PT &p) : x(p.x), y(p.y)    {}
    PT operator + (const PT &p)  const
    {
        return PT(x+p.x, y+p.y);
    }
    PT operator - (const PT &p)  const
    {
        return PT(x-p.x, y-p.y);
    }
    PT operator * (double c)     const
    {
        return PT(x*c,   y*c  );
    }
    PT operator / (double c)     const
    {
        return PT(x/c,   y/c  );
    }
    bool operator<(const PT &p)  const
    {
        return make_pair(x,y)<make_pair(p.x,p.y);
    }
    bool operator==(const PT &p)  const
    {
        return !(*this < p) && !(p < *this);
    }
};
double dot(PT p, PT q)
{
    return p.x*q.x+p.y*q.y;
}
double dist2(PT p, PT q)
{
    return sqrt(dot(p-q,p-q));
}
double cross(PT p, PT q)
{
    return p.x*q.y-p.y*q.x;
}
PT norm(PT x, double l)
{
    return x * sqrt(l*l / dot(x,x));
}
istream &operator>>(istream &is, PT &p)
{
    return is >> p.x >> p.y;
}
ostream &operator<<(ostream &os, const PT &p)
{
    return os << "(" << p.x << "," << p.y << ")";
}
/*around the origin*/
PT RotateCCW90(PT p)
{
    return PT(-p.y,p.x);
}
PT RotateCW90(PT p)
{
    return PT(p.y,-p.x);
}
PT RotateCCW(PT p, double t)
{
    return PT(p.x*cos(t)-p.y*sin(t), p.x*sin(t)+p.y*cos(t));
}
// project point c onto line through a and b (assuming a != b)
PT ProjectPointLine(PT a, PT b, PT c)
{
    return a + (b-a)*dot(c-a, b-a)/dot(b-a, b-a);
}
// project point c onto line segment through a and b (assuming a != b)
PT ProjectPointSegment(PT a, PT b, PT c)
{
    double r = dot(c-a, b-a)/dot(b-a,b-a);
    if (r < 0) return a;
    if (r > 1) return b;
    return a + (b-a)*r;
}

PT st, en;
vector< vector< pair<int, double > > > node;

int n;
map< pair< PT, double >, int > compress;

vector< pair< PT, double > > vec;

double dijkstra()
{
    set< pair< double, int > > st;
    st.insert({0.0, 0});
    vd dist(n+2, (double)-1);
    while(!st.empty())
    {
        pair<double, int > hoba = *st.begin();
        st.erase(st.begin());
        int idx = hoba.second;
        double cost = hoba.first;
        if (dist[idx] != -1) continue;
        dist[idx] = cost;
        if (idx == n+1) break;
        for(auto i : node[idx])
        {
            if (dist[i.first] == -1)
            {
                st.insert({cost + i.second, i.first});
            }
        }
    }
    return dist[n+1];
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> st >> en;
    int idx = 0;
    compress[{st, 0}] = idx++;
    compress[{en, 0}] = n+1;
    cin >> n;
    node = vector< vector< pair<int, double > > >(n+5);
    node[0].push_back({n+1, dist2(st, en)});
    node[n+1].push_back({0, dist2(st, en)});
    vec = vector< pair< PT, double> > (n);
    rep(i, 0, n)
    {
        cin >> vec[i].first >> vec[i].second;
        compress[{vec[i].first, vec[i].second}] = idx++;
        int temp = idx-1;
        node[0].push_back({temp, max(dist2(st, vec[i].first) - vec[i].second, 0.0)});
        node[n+1].push_back({temp, max(dist2(en, vec[i].first) - vec[i].second, 0.0)});
        node[temp].push_back({0, max(dist2(st, vec[i].first) - vec[i].second, 0.0)});
        node[temp].push_back({n+1, max(dist2(en, vec[i].first) - vec[i].second, 0.0)});
    }

    rep(i, 0, n)
    {
        rep(j, i+1, n)
        {
            int u = compress[{vec[i].first, vec[i].second}], v = compress[{vec[j].first, vec[j].second}];
            double cost = max(0.0, dist2(vec[i].first, vec[j].first) - vec[i].second - vec[j].second);
            node[u].push_back({v, cost});
            node[v].push_back({u, cost});
        }
    }
    cout << fixed << setprecision(9) << dijkstra();

    return 0;
}


Measured memory_bytes: 47488