#include <bits/stdc++.h>
#define loop(n) for (int ngtkana_is_genius = 0; ngtkana_is_genius < int(n); ngtkana_is_genius++)
#define rep(i, begin, end) for(int i = int(begin); i < int(end); i++)
#define all(v) v.begin(), v.end()
#define lint long long
auto cmn = [](auto& a, auto b){if (a > b) {a = b; return true;} return false;};
auto cmx = [](auto& a, auto b){if (a < b) {a = b; return true;} return false;};
void debug_impl() { std::cerr << std::endl; }
template <typename Head, typename... Tail>
void debug_impl(Head head, Tail... tail){
  std::cerr << " " << head;
  debug_impl(tail...);
}
#define debug(...)\
  std::cerr << std::boolalpha << "[" << #__VA_ARGS__ << "]:";\
  debug_impl(__VA_ARGS__);\
  std::cerr << std::noboolalpha;

template <typename T>
std::istream& operator>> (std::istream& is, std::vector<T>& v) {
  for (auto & x : v) is >> x;
  return is;
}

template <typename T>
std::ostream& operator<< (std::ostream& os, const std::vector<T>& v) {
  auto n = v.size();
  os << "{";
  for (size_t i = 0; i < n; i++)
    {os << (i > 0 ? "," : "") << v.at(i);}
  return os << "}";
}
template <typename... Args, std::size_t ... Inds>
std::ostream& tuple_output_impl(
  std::ostream& os,
  const std::tuple<Args...>& tuple,
  std::integer_sequence<std::size_t, Inds...>
)
{
  os << "(";
  (void)std::initializer_list<int>{(
    (void)(os << (Inds > 0 ? "," : "") << std::get<Inds>(tuple)), 0
  )...};
  return os << ")";
}

template <typename... Args>
std::ostream& operator<< (std::ostream& os, const std::tuple<Args...>& tuple)
 { return tuple_output_impl(os, tuple, std::index_sequence_for<Args...>()); }

template <typename... Args, std::size_t ... Inds>
std::istream& tuple_input_impl(
  std::istream& is,
  std::tuple<Args...>& tuple,
  std::integer_sequence<std::size_t, Inds...>
)
{
  (void)std::initializer_list<int>{(
    (void)(is >> std::get<Inds>(tuple)), 0
  )...};
  return is;
}
template <typename... Args>
std::istream& operator>> (std::istream& is, std::tuple<Args...>& tuple)
  { return tuple_input_impl(is, tuple, std::index_sequence_for<Args...>()); }

template < typename Cost >
class dijkstra {
    int                 n;
    int                 start;
    Cost                inf;
    std::vector< Cost > dist;
    std::vector< std::vector< std::pair< Cost, int > > > graph;

  public:
    dijkstra()=default;
    dijkstra(int n, int start, Cost inf) :
      n(n), start(start), inf(inf), dist(n, inf), graph(n){}

    void insert(int i, int j, Cost cost)
      { graph.at(i).emplace_back(cost, j); }

    void build() {
      std::priority_queue<
        std::pair< Cost, int >,
        std::vector< std::pair< Cost, int > >,
        std::greater< std::pair< Cost, int > >> que;
      que.emplace(0, start);
      while (!que.empty()) {
        Cost d; int crr; std::tie(d, crr) = que.top(); que.pop();
        if (dist.at(crr) <= d) continue;
        dist.at(crr) = d;
        for (auto pair : graph.at(crr)) {
          Cost cost; int nxt; std::tie(cost, nxt) = pair;
          if (dist.at(nxt) <= d + cost) continue;
          que.emplace(d + cost, nxt);
        }
      }
    }

    auto collect() const { return dist; }

    auto at(int i) const { return dist.at(i); }
};

int main() {
  std::cin.tie(0); std::cin.sync_with_stdio(false);
  double xs, ys, xg, yg;
  std::cin >> xs >> ys >> xg >> yg;
  int n; std::cin >> n;
  auto points = std::vector< std::tuple< double, double, double > >(n);
  for (auto & p : points) {
    double x, y, r;
    std::cin >> x >> y >> r;
    p = std::make_tuple(x, y, r);
  }
  points.emplace_back(xs, ys, 0.);
  points.emplace_back(xg, yg, 0.);
  constexpr double inf = 1e20;
  auto dij = dijkstra< double >(n + 2, n, inf);
  rep(i, 0, n + 2) rep(j, 0, n + 2) {
    if (i == j) continue;
    double xi, yi, ri; std::tie(xi, yi, ri) = points.at(i);
    double xj, yj, rj; std::tie(xj, yj, rj) = points.at(j);
    auto d = std::sqrt(std::pow(xi - xj, 2) + std::pow(yi - yj, 2));
    auto cost = std::max(0., d - ri - rj);
    dij.insert(i, j, cost);
  }
  dij.build();
  // debug(dij.collect());
  std::cout << std::setprecision(10) <<  dij.at(n + 1) << std::endl;
  return 0;
}


Measured memory_bytes: 26732