{-# LANGUAGE BangPatterns #-}
import Control.Arrow
import Control.Monad.Fix
import Data.Foldable
import Data.Ord
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import qualified Data.ByteString.Char8 as B
import System.IO.Unsafe
import Debug.Trace

instance Bounded Double where
  maxBound = fromIntegral (maxBound :: Int)
  minBound = fromIntegral (minBound :: Int)

uread :: VUM.Unbox a => Int -> VUM.IOVector a -> a
uread i v = unsafePerformIO $ VUM.read v i

uwrite :: VUM.Unbox a => Int -> a -> VUM.IOVector a -> VUM.IOVector a
uwrite i a v = unsafePerformIO $ VUM.write v i a >> return v

uswap :: VUM.Unbox a => Int -> Int -> VUM.IOVector a -> VUM.IOVector a
uswap i j v = unsafePerformIO $ VUM.swap v i j >> return v

ufreeze :: VUM.Unbox a => VUM.IOVector a -> VU.Vector a
ufreeze v = unsafePerformIO $ VU.freeze v

uthaw :: VUM.Unbox a => VU.Vector a -> VUM.IOVector a
uthaw = unsafePerformIO . VU.thaw

data PQueue a = PQueue Int (VUM.IOVector a)

new :: VUM.Unbox a => Int -> PQueue a
new s = PQueue 0 $ unsafePerformIO $ VUM.new s

push :: Ord a => VUM.Unbox a => a -> PQueue a -> PQueue a
push a (PQueue k vec) = PQueue (k + 1) vec'
 where
  vec' = up k a $ uwrite k a vec

  up i cv vec = (\(_, v) -> v) $ fix
    ( \f (ci, vec) ->
      let pi = (ci - 1) `div` 2
          pv = uread pi vec
      in  if 0 < ci && cv < pv
            then let vec' = uswap pi ci vec in vec' `seq` f (pi, vec')
            else (ci, vec)
    )
    (i, vec)

popMin :: (Ord a, Bounded a, VUM.Unbox a) => PQueue a -> Maybe (a, PQueue a)
popMin (PQueue k vec) | k < 0     = Nothing
                      | otherwise = Just (uread 0 vec, PQueue (k - 1) vec')
 where
  vec' = let v = uswap (k - 1) 0 vec in v `seq` down 0 (uread 0 vec) v

  down i cv vec = (\(_, v) -> v) $ fix
    ( \f (ci, vec) ->
      let li = ci * 2 + 1
          lv = if li < k - 1 then uread li vec else maxBound
          ri = ci * 2 + 2
          rv = if ri < k - 1 then uread ri vec else maxBound
      in  if cv <= lv && cv <= rv
            then (ci, vec)
            else
              let p    = if lv > rv then ri else li
                  vec' = uswap p ci vec
              in  vec' `seq` f (p, vec')
    )
    (i, vec)

popMin' :: (Ord a, Bounded a, VUM.Unbox a) => PQueue a -> (a, PQueue a)
popMin' pq = maybe (error "size < 0") id $ popMin pq

dijkstra
  :: Int  -- ^ nodes
  -> (Int -> VU.Vector (Int, Double))  -- ^ edges from i-th node: (end, cost)
  -> Int  -- ^ start node
  -> VU.Vector Double  -- ^ constructed graph
dijkstra n edges s = ufreeze $ snd $ fix
  ( \f (nodes, costs) -> case popMin nodes of
    Nothing              -> (nodes0, costs)
    Just ((c, n), nodes) -> if c <= uread n costs
      then
        let es = edges n
        in  f $ VU.foldl'
              ( \(ns, cs) (e, ec) ->
                let c' = c + ec
                in  if c' < uread e costs
                      then (push (c', e) ns, uwrite e c' cs)
                      else (ns, cs)
              )
              (nodes, costs)
              es
      else f (nodes, costs)
  )
  (nodes0, costs0)
 where
  costs0 :: VUM.IOVector Double
  costs0 = uwrite s 0 (uthaw $ VU.replicate n $ fromIntegral (maxBound :: Int))

  nodes0 :: PQueue (Double, Int)
  nodes0 = push (0, s) (new (n * n))

solve :: Int -> Int -> Int -> Int -> Int -> VU.Vector (Int, Int, Int) -> Double
solve xs ys xt yt n xyr = graph VU.! (n + 1)
 where
    -- VU.filter (\(x,y,r) -> dist2 (xs,ys) (x,y) <= distMax) xyr
  dist2 (x1, y1) (x2, y2) = (x1 - x2) ^ 2 + (y1 - y2) ^ 2

  dist2C :: (Int, Int, Int) -> (Int, Int, Int) -> Double
  dist2C (x1, y1, r1) (x2, y2, r2) =
    ( sqrt (fromIntegral $ (x1 - x2) ^ 2 + (y1 - y2) ^ 2)
      - fromIntegral (r1 + r2)
      )
      `max` 0

  distMax = dist2 (xs, ys) (xt, yt)

  toIndex (i, j) = i * (n + 2) + j

  distMemo = ufreeze $ foldl'
    ( \acc (i, j) ->
      let c1 = if i == n
            then (xs, ys, 0)
            else if i == n + 1 then (xt, yt, 0) else xyr VU.! i
          c2 = if j == n
            then (xs, ys, 0)
            else if j == n + 1 then (xt, yt, 0) else xyr VU.! j
      in  uwrite (toIndex (i, j)) (dist2C c1 c2) acc
    )
    (uthaw $ VU.replicate ((n + 2) * (n + 2)) 0.0)
    [ (i, j) | i <- [0 .. n + 1], j <- [0 .. n + 1], i /= j ]
  graph = dijkstra
    (n + 2)
    ( \e -> VU.map (\i -> (i, distMemo VU.! toIndex (i, e)))
      $ VU.fromList [0 .. n + 1]
    )
    n

main = do
  let readInt = fmap (second B.tail) . B.readInt

  (xs, ys, xt, yt) <-
    (\vec -> (vec VU.! 0, vec VU.! 1, vec VU.! 2, vec VU.! 3))
    .   VU.unfoldrN 4 readInt
    <$> B.getLine
  n   <- (\vec -> (vec VU.! 0)) . VU.unfoldrN 1 readInt <$> B.getLine
  xyr <-
    VU.replicateM n
    $   (\vec -> (vec VU.! 0, vec VU.! 1, vec VU.! 2))
    .   VU.unfoldrN 3 readInt
    <$> B.getLine
  print $ solve xs ys xt yt n xyr
