// Original C++ solution (slower):
#include<cstdio>

#include<cstring>

#include<algorithm>

#include<cmath>

#define MAXN 1000

//const double INF=;

using namespace std;

double sx,sy,tx,ty;

struct Circle

{

	double x,y,r;

}C[MAXN+5];

bool vis[MAXN+5];

double G[MAXN+5][MAXN+5];

void Init()

{

	for(int i=0;i<=MAXN+3;i++)

		for(int j=0;j<=MAXN+3;j++)

			G[i][j]=-1.0;

}

double Getlen(double x1,double y1,double x2,double y2)

{

	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));

}

bool Intersect(int a,int b)

{

	double len=Getlen(C[a].x,C[a].y,C[b].x,C[b].y);

	double totr=C[a].r+C[b].r;

	if(len<=totr)

		return true;

	return false;

}

int n;

double dist[MAXN+5];

double Dijkstra(int s)

{

	memset(vis,0,sizeof(vis));

	for(int i=0;i<=MAXN+3;i++)

		dist[i]=-1;

	dist[s]=0;

	vis[s]=true;

	int u=s,nu,cnt=1;

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

	{

		double mindist=-1;

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

		{

			if(G[u][v]==-1)

				continue;

			if(dist[v]>dist[u]+G[u][v]||dist[v]==-1)

				dist[v]=dist[u]+G[u][v];

			if((mindist==-1||dist[v]<mindist)&&vis[v]==false)

			{

				mindist=dist[v];

				nu=v;

			}

		}

		vis[nu]=true;

		u=nu;

	}

	return dist[n];

}

int main()

{

	Init();

	scanf("%lf %lf %lf %lf",&sx,&sy,&tx,&ty);

	scanf("%d",&n);

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

		scanf("%lf %lf %lf",&C[i].x,&C[i].y,&C[i].r);

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

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

		{

			double len=max(Getlen(C[i].x,C[i].y,C[j].x,C[j].y)-C[i].r-C[j].r,0.0);

			if(G[i][j]==-1||len<G[i][j])

				G[i][j]=len;

		}

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

	{

		double len=max(Getlen(sx,sy,C[i].x,C[i].y)-C[i].r,0.0);

		if(G[i][0]==-1||len<G[0][i])

			G[i][0]=G[0][i]=len;

		len=max(Getlen(tx,ty,C[i].x,C[i].y)-C[i].r,0.0);

		if(G[i][n+1]==-1||len<G[i][n+1])

			G[i][n+1]=G[n+1][i]=len;

	}

	n++;

	G[0][n]=G[n][0]=Getlen(sx,sy,tx,ty);

	double ans=Dijkstra(0);

	printf("%.10lf\n",ans);

	return 0;

}

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

 * Author : Andrew J

*/

#include <bits/stdc++.h>

using namespace std;

#define rall(x) x.rbegin() , x.rend()

#define all(x) x.begin() , x.end()

#define fi first

#define se second

#define pb push_back

using ll = long long;

using ii = pair <int , int>;

using di = pair <double , int>;

using minHeap = priority_queue <di , vector <di> , greater <di>>;

void in(int &x);

const double INF = 1e18;

const int N = 1050;

#define singleCase

// #define multipleCase

int xs, ys, xf, yf, n;

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

bool vis[N];



double distBetweenPoints(double x1 , double y1 , double x2 , double y2) {

  return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));

}



double getDist(int u , int v) {

  double shortestPath = distBetweenPoints(x[u] , y[u] , x[v] , y[v]);

  return max(0.0 , shortestPath - r[u] - r[v]);

}



void work() {

  scanf("%d%d%d%d%d" , &xs , &ys , &xf , &yf , &n);

  x[0] = xs, y[0] = ys, r[0] = 0;

  x[n + 1] = xf, y[n + 1] = yf, r[n + 1] = 0;

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

    scanf("%lf%lf%lf" , &x[i] , &y[i] , &r[i]);

  }

  fill (d , d + N , INF);

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

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

      dist[i][j] = getDist(i , j);

      dist[j][i] = dist[i][j];

    }

  }

  minHeap pq;

  pq.push({0 , 0});

  double sol = -1;

  while (pq.size()) {

    di cur = pq.top(); pq.pop();

    double cd = cur.fi;

    int u = cur.se;

    if (vis[u]) continue;

    vis[u] = 1, d[u] = cd;

    if (u == n + 1) {

      sol = cd;

      break;

    }

    for (int v = 0 ; v <= n + 1 ; v++) {

      if (d[v] > cd + dist[u][v]) {

        pq.push({cd + dist[u][v] , v});

      }

    }

  }

  printf("%.10lf\n" , sol);

  return;

}



int main() {

  #ifdef multipleCase

    int nQ; in(nQ);

    while (nQ--)

      work();

  #endif

  #ifdef singleCase

    work();

  #endif

  return 0;

}



void in(int &x) {

	bool neg = false;

	register int c;

	x = 0;

	c = getchar();

	if(c == '-') {

		neg = true;

		c = getchar();

	}

	for (; c > 47 && c < 58; c = getchar())

	  x = (x << 1) + (x << 3) + c - 48;

	if (neg) x *= -1;

}


// Fastest known solution for this problem: