import Data.List
import Data.Maybe
import Control.Monad
import Data.Array.IO
import qualified Data.Set as S
import qualified Data.ByteString.Char8 as B

kruskalIO (n,edge) = do
 forest <- newListArray (0,n-1) [0..n-1] :: IO (IOUArray Int Int)
 ret <- foldM makepath (forest,0) edge
 return ret

makepath (forest,acc) ((a,b),d) = do
 rep1 <- untilFix (readArray forest) a
 rep2 <- untilFix (readArray forest) b
 if rep1 /= rep2
  then do
   writeArray forest rep2 rep1
   writeArray forest b rep1
   return (forest, acc+d)
  else do
   return (forest, acc)

main = do
 getLine
 xys <- intPairs <$> B.getContents
 ret <- snd <$> kruskalIO (mkedge xys)
 print ret

mkedge xys = (n,edge)
 where
  xyis = zip (snub xys) [0..]
  n = length xyis
  xysx = sortOn fst xyis
  xysy = sortOn (snd.fst) xyis
  edgex = zipWith make xysx (tail xysx)
  edgey = zipWith make xysy (tail xysy)
  edge = sortOn snd (edgex ++ edgey)

make ((xi,yi),i) ((xj,yj),j) = ((a,b),d)
 where
  a = min i j
  b = max i j
  d = min (abs (xj-xi)) (abs (yj-yi))

snub = S.toList . S.fromList
intPairs = map ((\[x,y]->(x,y)) . map (fst . fromJust . B.readInt) . B.words) . B.lines
untilFix f x0 = f x0 >>= \x -> if x == x0 then return x else untilFix f x