using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

static class Program
{
    class PriorityQueue<T>
    {
        private readonly List<T> m_list;
        private readonly Func<T, T, int> m_compare;
        public int Count { get; private set; }
        public PriorityQueue(int capacity, Func<T, T, int> compare)
        {
            m_list = new List<T>(capacity);
            m_compare = compare;
            Count = 0;
        }
        private int Add(T value)
        {
            if (Count == m_list.Count)
            {
                m_list.Add(value);
            }
            else
            {
                m_list[Count] = value;
            }
            return Count++;
        }
        private void Swap(int a, int b)
        {
            T tmp = m_list[a];
            m_list[a] = m_list[b];
            m_list[b] = tmp;
        }
        public void Enqueue(T value)
        {
            int c = Add(value);
            while (c > 0)
            {
                int p = (c - 1) / 2;
                if (m_compare(m_list[c], m_list[p]) < 0) { Swap(p, c); } else { break; }
                c = p;
            }
        }
        public T Dequeue()
        {
            T value = m_list[0];
            m_list[0] = m_list[--Count];
            int p = 0;
            while (true)
            {
                int c1 = p * 2 + 1;
                int c2 = p * 2 + 2;
                if (c1 >= Count) { break; }
                int c = (c2 >= Count || m_compare(m_list[c1], m_list[c2]) < 0) ? c1 : c2;
                if (m_compare(m_list[c], m_list[p]) < 0) { Swap(p, c); } else { break; }
                p = c;
            }
            return value;
        }
    }

    class Point
    {
        public readonly double x;
        public readonly double y;
        public Point(double x, double y)
        {
            this.x = x;
            this.y = y;
        }
        public static double Distance(Point a, Point b)
        {
            double x = a.x - b.x;
            double y = a.y - b.y;
            return Math.Sqrt(x * x + y * y);
        }
    }

    class Circle
    {
        public readonly Point o;
        public readonly double r;
        public Circle(double[] args)
        {
            o = new Point(args[0], args[1]);
            r = args[2];
        }
    }

    static double Solve(Point s, Point t, int N, Circle[] circles)
    {
        const double INF = double.MaxValue * 0.25;
        var D = new double[N + 2][];
        for (int i = 0; i < N + 2; ++i)
        {
            D[i] = Enumerable.Repeat(INF, N + 2).ToArray();
            D[i][i] = 0;
        }
        D[0][N + 1] = Point.Distance(s, t);
        for (int i = 0; i < N; ++i)
        {
            double ds = Math.Max(Point.Distance(s, circles[i].o) - circles[i].r, 0);
            D[0][i + 1] = ds;
            D[i + 1][0] = ds;

            double dt = Math.Max(Point.Distance(t, circles[i].o) - circles[i].r, 0);
            D[N + 1][i + 1] = dt;
            D[i + 1][N + 1] = dt;

            for (int j = i + 1; j < N; ++j)
            {
                double d = Math.Max(Point.Distance(circles[i].o, circles[j].o) - circles[i].r - circles[j].r, 0);
                D[i + 1][j + 1] = d;
                D[j + 1][i + 1] = d;
            }
        }
        var f = new bool[N + 2];
        var q = new PriorityQueue<int>(N + 2, (a, b) => D[0][a].CompareTo(D[0][b]));
        for (int i = 0; i < N; ++i)
        {
            f[i + 1] = true;
            q.Enqueue(i + 1);
        }
        while (q.Count > 0)
        {
            int i = q.Dequeue();
            f[i] = false;
            for (int j = 1; j < N + 2; ++j)
            {
                if (D[0][i] + D[i][j] < D[0][j])
                {
                    D[0][j] = D[0][i] + D[i][j];
                    if (j < N + 1 && !f[j])
                    {
                        f[j] = true;
                        q.Enqueue(j);
                    }
                }
            }
        }
        return D[0][N + 1];
    }

    static void Main(string[] args)
    {
        var V1 = Array.ConvertAll(Console.ReadLine().Split(), double.Parse);
        var s = new Point(V1[0], V1[1]);
        var t = new Point(V1[2], V1[3]);
        int N = int.Parse(Console.ReadLine());
        var circles = new Circle[N];
        for (int i = 0; i < N; ++i)
        {
            var V2 = Array.ConvertAll(Console.ReadLine().Split(), double.Parse);
            circles[i] = new Circle(V2);
        }
        Console.WriteLine(Solve(s, t, N, circles));
    }
}


Measured memory_bytes: 39384