// Original C++ solution (slower):
/*

Hanit Banga

Problem: 

*/



#include <iostream>

#include <cstdio>

#include <vector>

#include <cmath>

// #include <climits>

#include <iomanip>

#include <queue>



using namespace std;



#define pb push_back

#define node second

#define weight first



typedef long long ll;

typedef pair <int, int> pii;

typedef pair <double, int> edge;

typedef pair <ll, ll> pll;



const int maxNodes = 1e4 + 10, N = 1e4 + 10; //Set this value

const double maxDist = 1e18;



vector <edge> g[maxNodes];

priority_queue <edge, vector <edge>, greater <edge> > q;

bool visited[maxNodes];

double dist[maxNodes];



void init(int);

void dijkstra(int);

double distance(int, int);



double x[N], y[N], r[N];



int main()

{

    int n;

    cin >> x[0] >> y[0] >> x[1] >> y[1] >> n;

    r[0] = r[1] = 0;

    n += 2;



    init(n);



    for (int i = 2; i < n; ++i)

        cin >> x[i] >> y[i] >> r[i];



    for (int i = 0; i < n; ++i)

    {

        for (int j = i+1; j < n; ++j)

        {

            double d = max(0.0, distance(i,j) - r[i] - r[j]);

            g[i].pb({d, j});

            g[j].pb({d, i});

        }

    }



    dijkstra(0);

    cout << setprecision(10) << fixed << dist[1];

}



void init(int n = maxNodes-1)

{

    //Initializes everything to empty, can be optimized by passing n

    //Include <climits>



    while (!q.empty())

        q.pop();



    for (int i = 0; i <= n; ++i)

    {

        g[i].clear();

        visited[i] = false;

        dist[i] = maxDist;

    }

}



void dijkstra(int startNode)

{

    //Stores shortest distance from startNode to every node in array dist

    //Time complexity is O(Elog2(V))



    dist[startNode] = 0.0;

    q.push({0.0, startNode});



    while (!q.empty())

    {

        while (!q.empty() and visited[q.top().node])

            q.pop();



        if (q.empty())

            break;



        int temp = q.top().node;

        q.pop();



        // if (temp == destNode)

        //     return;



        for (auto i : g[temp])

        {

            if (!visited[i.node])

            {

                if (dist[temp] + i.weight < dist[i.node])

                {

                    dist[i.node] = dist[temp] + i.weight;

                    q.push({dist[i.node], i.node});

                }

            }

        }



        visited[temp] = true;

    }

}



double distance(int i, int j)

{

    return sqrt((x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]));

}

// Optimized solution to the same problem (faster):
/*

Cerberus97

Hanit Banga

*/



#include <iostream>

#include <iomanip>

#include <cmath>

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <map>

#include <set>

#include <queue>

#include <stack>

#include <vector>

#include <algorithm>



using namespace std;



#define pb push_back

#define fast_cin() ios_base::sync_with_stdio(false); cin.tie(NULL)

#define sqr(x) (x) * (x)



typedef long long ll;

typedef long double ld;

typedef pair <int, int> pii;

typedef pair <ll, ll> pll;



const int N = 1e3 + 10;

const ld inf = 1e18;



struct circle {

	ld x, y, r = 0;

	ld dist(circle &c) {

		ld ans = sqr(x - c.x) + sqr(y - c.y);

		ans = sqrt(ans) - r - c.r;

		ans = max(ld(0), ans);

		return ans;

	}

} p[N];



ld g[N][N];



ld dijsktra(int s, int t, int n);



int main() {

	cin >> p[1].x >> p[1].y >> p[2].x >> p[2].y;

	int n; cin >> n;

	n += 2;

	for (int i = 3; i <= n; ++i) {

		cin >> p[i].x >> p[i].y >> p[i].r;

	}

	for (int i = 1; i <= n; ++i) {

		for (int j = i + 1; j <= n; ++j) {

			g[i][j] = g[j][i] = p[i].dist(p[j]);

		}

	}

	cout << fixed << setprecision(20) << dijsktra(1, 2, n);

}



ld dijsktra(int s, int t, int n) {

	vector<ld> dist(n + 1);

	vector<bool> seen(n + 1);

	for (int i = 0; i <= n; ++i) {

		dist[i] = inf;

		seen[i] = 0;

	}

	dist[s] = 0;

	for (int i = 0; i < n; ++i) {

		int cur = 0;

		for (int j = 1; j <= n; ++j) {

			if (!seen[j] and dist[j] < dist[cur]) {

				cur = j;

			}

		}

		for (int j = 1; j <= n; ++j) {

			if (dist[cur] + g[cur][j] < dist[j]) {

				dist[j] = dist[cur] + g[cur][j];

			}

		}

		seen[cur] = true;

	}

	return dist[t];

}

// Fastest known solution for this problem: