{-# LANGUAGE Strict #-}
import Control.Arrow
import Control.Monad.Fix
import Data.Foldable
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as VMM
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VM
import qualified Data.ByteString.Char8 as B
import qualified Data.Set as S
import System.IO.Unsafe
import Debug.Trace

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

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

umodify :: VU.Unbox a => Int -> (a -> a) -> VM.IOVector a -> VM.IOVector a
umodify i f v = unsafePerformIO $ VM.modify v f i >> return v

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

ufreeze :: VU.Unbox a => VM.IOVector a -> VU.Vector a
ufreeze = unsafePerformIO . VU.freeze

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 S.minView nodes of
    Nothing -> (S.empty,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 (S.insert (c',e) ns, uwrite e c' cs)
                else (ns,cs)
              ) (nodes,costs) es
        else f (nodes,costs)) (nodes0,costs0)
  where
    costs0 :: VM.IOVector Double
    costs0 = uwrite s 0 (uthaw $ VU.replicate n $ fromIntegral (maxBound :: Int))

    nodes0 :: S.Set (Double,Int)
    nodes0 = S.singleton (0,s)

solve :: Int -> Int -> Int -> Int -> Int -> VU.Vector (Int,Int,Int) -> Double
solve xs ys xt yt n xyr = graph VU.! (n+1)
  where
    big = fromIntegral (maxBound :: Int)

    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

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

    {-# NOINLINE distMemo #-}
    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)) big) [(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
