// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

using ll = int64_t;

using ld = long double;



template<typename T>

class Dijk{

    private:

        ll n;

        vector<vector<pair<ll, T>>> v;

        function<bool(pair<ll, T>, pair<ll, T>)> comp;

    public:

        T INF;

        

        Dijk(const vector<vector<pair<ll, T>>> &v, T INF, function<bool(pair<ll, T>, pair<ll, T>)> comp){

            this->n = v.size();

            this->v = v;

            this->INF = INF;

            this->comp = comp;

        }

        

        vector<T> dijk(ll start){

            vector<T> d(n, INF);

            d[start] = 0;

            priority_queue<pair<ll, T>, vector<pair<ll, T>>, function<bool(pair<ll, T>, pair<ll, T>)>> q(comp);

            q.push(pair<ll, T>(start, 0));

            while(q.size()){

                pair<ll, T> now = q.top();

                q.pop();

                if(d[now.first] < now.second){

                    continue;

                }

                for(auto next : v[now.first]){

                    if(d[next.first] == INF || d[now.first] + next.second < d[next.first]){

                        d[next.first] = d[now.first] + next.second;

                        q.push(pair<ll, T>(next.first, d[now.first] + next.second));

                    }

                }

            }

            return d;

        }

};



struct Circle{

    ld x, y, r;

};



vector<vector<pair<ll, ld>>> v(1002);

ll N;



ld dist(pair<ld, ld> x, pair<ld, ld> y){

    return sqrt(pow(x.first - y.first, 2) + pow(x.second - y.second, 2));

}



ld dist(Circle a, Circle b){

    return dist(pair<ld, ld>(a.x, a.y), pair<ld, ld>(b.x, b.y));

}



int main(){

    pair<ld, ld> start, goal;

    cin >> start.first >> start.second >> goal.first >> goal.second;

    cin >> N;

    vector<Circle> C;

    C.push_back(Circle{start.first, start.second, 0});

    C.push_back(Circle{goal.first, goal.second, 0});

    for(ll i = 0; i < N; i++){

        ld x, y, r;

        cin >> x >> y >> r;

        C.push_back(Circle{x, y, r});

    }

    for(ll i = 0; i < C.size(); i++) for(ll j = 0; j < C.size(); j++) v[i].push_back(pair<ll, ld>(j, max<ld>(0, dist(C[i], C[j]) - C[i].r - C[j].r)));

    Dijk<ld> D(v, 5e15, [&](pair<ll, ld> a, pair<ll, ld> b){return a.second > b.second;});

    printf("%.1333Lf\n", D.dijk(0)[1]);

    return 0;

}


// Optimized solution to the same problem (faster):
#include <limits>

#include <initializer_list>

#include <utility>

#include <bitset>

#include <tuple>

#include <type_traits>

#include <functional>

#include <string>

#include <array>

#include <deque>

#include <list>

#include <queue>

#include <stack>

#include <vector>

#include <map>

#include <set>

#include <unordered_map>

#include <unordered_set>

#include <iterator>

#include <algorithm>

#include <complex>

#include <random>

#include <numeric>

#include <iostream>

#include <iomanip>

#include <sstream>

#include <regex>

#include <cassert>

#include <cstddef>

// #include <variant>



// Yay!!

#define endl codeforces



// macros for iterator

#define ALL(v) std::begin(v), std::end(v)

#define ALLR(v) std::rbegin(v), std::rend(v)



// alias

using ll = std::int64_t;

using ull = std::uint64_t;

using pii = std::pair<int, int>;

using tii = std::tuple<int, int, int>;

using pll = std::pair<ll, ll>;

using tll = std::tuple<ll, ll, ll>;

template <typename T> using vec = std::vector<T>;

template <typename T> using vvec = vec<vec<T>>;



// variadic min/max

template <typename T> const T& var_min(const T &t) { return t; }

template <typename T> const T& var_max(const T &t) { return t; }

template <typename T, typename... Tail> const T& var_min(const T &t, const Tail&... tail) { return std::min(t, var_min(tail...)); }

template <typename T, typename... Tail> const T& var_max(const T &t, const Tail&... tail) { return std::max(t, var_max(tail...)); }



// variadic chmin/chmax

template <typename T, typename... Tail> void chmin(T &t, const Tail&... tail) { t = var_min(t, tail...); }

template <typename T, typename... Tail> void chmax(T &t, const Tail&... tail) { t = var_max(t, tail...); }



// multi demension array

template <typename T, std::size_t Head, std::size_t... Tail> struct multi_dim_array { using type = std::array<typename multi_dim_array<T, Tail...>::type, Head>; };

template <typename T, std::size_t Head> struct multi_dim_array<T, Head> { using type = std::array<T, Head>; };

template <typename T, std::size_t... Args> using mdarray = typename multi_dim_array<T, Args...>::type;



// fill container

// template <typename T, typename F, typename... Args> 

// void fill_seq(T &t, F f, Args... args) { if constexpr (std::is_invocable<F, Args...>::value) { t = f(args...); } else { for (ssize_t i = 0; i < t.size(); i++) fill_seq(t[i], f, args..., i); } }



// make multi dimension vector

template <typename T> vec<T> make_v(ssize_t sz) { return vec<T>(sz); }

template <typename T, typename... Tail> auto make_v(ssize_t hs, Tail&&... ts) { auto v = std::move(make_v<T>(std::forward<Tail>(ts)...)); return vec<decltype(v)>(hs, v); }



// init

namespace init__ { 

struct InitIO { InitIO() { std::cin.tie(nullptr); std::ios_base::sync_with_stdio(false); std::cout << std::fixed << std::setprecision(30); } } init_io; 

}





int main() {

    ll a0, b0, a1, b1;

    std::cin >> a0 >> b0 >> a1 >> b1;

    vec<tll> cv;

    cv.emplace_back(a0, b0, 0);

    ll n;

    std::cin >> n;

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

        ll a, b, r;

        std::cin >> a >> b >> r;

        cv.emplace_back(a, b, r);

    }

    cv.emplace_back(a1, b1, 0);



    auto pow2 = [](ll x) { return x * x; };



    vvec<std::pair<ll, double>> g(n + 2);

    for (ll i = 0; i < n + 2; i++) for (ll j = i + 1; j < n + 2; j++) {

        auto a = cv[i], b = cv[j];

        ll x0, y0, r0, x1, y1, r1;

        std::tie(x0, y0, r0) = a;

        std::tie(x1, y1, r1) = b;

        ll dx = x0 - x1;

        ll dy = y0 - y1;

        ll d2 = pow2(dx) + pow2(dy);

        double cost = 0;

        if (pow2(r0 + r1) < d2) cost = std::sqrt(d2) - (r0 + r1);

        g[i].emplace_back(j, cost);

        g[j].emplace_back(i, cost);

    }



    using node = std::pair<double, ll>;

    std::priority_queue<node, vec<node>, std::greater<node>> pq;

    const double inf = 5e15;

    pq.emplace(0, 0);

    vec<double> dists(n + 2, inf);

    dists[0] = 0;

    while (pq.size()) {

        double d;

        ll cur;

        std::tie(d, cur) = pq.top();

        pq.pop();

        if (dists[cur] < d) continue;

        for (auto &&e : g[cur]) {

            double cost;

            ll nxt;

            std::tie(nxt, cost) = e;

            double nd = cost + d;

            if (dists[nxt] <= nd) continue;

            dists[nxt] = nd;

            pq.emplace(nd, nxt);

        }

    }



    std::cout << dists.back() << "\n";

    return 0;

}


// Fastest known solution for this problem: