Problem:
Score : 500 points

Problem Statement

There are N towns on a plane. The i-th town is located at the coordinates (x_i,y_i). There may be more than one town at the same coordinates.

You can build a road between two towns at coordinates (a,b) and (c,d) for a cost of min(|a-c|,|b-d|) yen (the currency of Japan). It is not possible to build other types of roads.

Your objective is to build roads so that it will be possible to travel between every pair of towns by traversing roads. At least how much money is necessary to achieve this?

Constraints

2 ≤ N ≤ 10^5

0 ≤ x_i,y_i ≤ 10^9

All input values are integers.

Input

Input is given from Standard Input in the following format:

N
x_1 y_1
x_2 y_2
:
x_N y_N

Output

Print the minimum necessary amount of money in order to build roads so that it will be possible to travel between every pair of towns by traversing roads.

Sample Input 1

3
1 5
3 9
7 8

Sample Output 1

3

Build a road between Towns 1 and 2, and another between Towns 2 and 3. The total cost is 2+1=3 yen.

Sample Input 2

6
8 3
4 9
12 19
18 1
13 5
7 6

Sample Output 2

8

Solution in Haskell (GHC 7.10.3) (judge verdict: Accepted)

{-# OPTIONS_GHC -O2 -funbox-strict-fields #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
{-# OPTIONS_GHC -fno-warn-unused-binds #-}
{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}
{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
{-# LANGUAGE OverloadedStrings #-}
-- {-# LANGUAGE FlexibleContexts #-}
-- {-# LANGUAGE MultiWayIf #-}
-- {-# LANGUAGE BangPatterns #-}
-- {-# LANGUAGE ViewPatterns #-}
-- {-# LANGUAGE TupleSections #-}

import           System.IO hiding (char8)
import           Control.Applicative
import           Control.Monad
import           Control.Monad.ST
import           Data.List hiding (find)
import           Data.Tuple
import           Data.Int
import           Data.Char
import           Data.Function (on, (&))
import           Data.Ord (comparing)
import           Data.Monoid (mappend)
import           Data.Array
-- import           Data.Array.Unboxed
-- import           Data.Array.IArray
import           Data.Array.ST
import           Data.Array.MArray
-- import           Data.Array.Unsafe
-- import           Data.Array.Base(unsafeRead, unsafeWrite)
-- import           Data.Array.IO
import           Data.Ix
import           Data.Maybe
-- import           Data.Monoid hiding ((<>))
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy.Char8 as BL
import           Data.ByteString.Builder
-- import           Data.Graph
-- import           Data.Vector.Unboxed ((//), (++), (!), (!?))
-- import qualified Data.Vector.Unboxed as U
-- import           Data.IntSet (IntSet)
-- import qualified Data.IntSet as IntSet
-- import           Data.IntMap.Strict (IntMap)
-- import qualified Data.IntMap.Strict as IntMap
import           Data.Sequence ((|>), (<|), (><),ViewR(..), ViewL(..), Seq)
import qualified Data.Sequence              as Seq
-- import           Data.Foldable (toList, minimumBy)
-- import           Debug.Trace

main = do
  n <- readInt1 <$> BS.getLine
  xys <- map readInt2 <$> replicateM n BS.getLine
  print . solve n $ unzip xys

-- solve :: Int -> ([Int], [Int]) -> Int
solve n (xs,ys) = sum $ kruskal n edges
  where
    edges = sortOn snd $ mkEdges xs ++ mkEdges ys
    mkEdges :: [Int] -> [Edge]
    mkEdges ns = zip [1..] ns
        & sortOn snd
        & \ms -> zipWith ((,) **** flip (-)) ms $ tail ms

(****) :: (a -> b -> c) -> (a' -> b' -> c') -> (a, a') -> (b, b') -> (c, c')
(****) f g (a, a') (b, b') = (f a b, g a' b')
infixr 3 ****

type Edge = ((Node, Node), Cost)
type Node = Int
type Cost = Int
kruskal :: Int -> [Edge] -> [Cost]
kruskal n es = runST $ do
  uf <- newUnionFind n
  k' uf es []
  where
    k' :: UnionFind s -> [Edge] -> [Cost] -> ST s [Cost]
    k' _ [] es' = return es'
    k' uf (((x,y),c):es) es' = do
      united <- find uf x y
      if united
        then k' uf es es'
        else unite uf x y >> k' uf es (c:es')


-- libs
-- http://jng.imagine27.com/index.php/2012-08-22-144618_purely-functional-data-structures-algorithms-union-find-haskell.html

-- Code from http://kwangyulseo.com/2014/01/30/implementing-union-find-algorithms-in-haskell/
data UnionFind s = UnionFind {
    ids:: STUArray s Int Int
  , szs:: STUArray s Int Int
  }

newUnionFind :: Int -> ST s (UnionFind s)
newUnionFind n = liftM2 UnionFind (newListArray (1, n) [1..n]) (newArray (1, n) 1)

find :: UnionFind s -> Int -> Int -> ST s Bool
find uf p q = liftM2 (==) (root uf p) (root uf q)

root :: UnionFind s -> Int -> ST s Int
root uf i = do
    ix <- readArray (ids uf) i
    if ix /= i
        then do
            gpid <- readArray (ids uf) ix
            writeArray (ids uf) i gpid
            root uf ix
        else return i

unite :: UnionFind s -> Int -> Int -> ST s ()
unite uf p q = do
    i <- root uf p
    j <- root uf q
    szi <- readArray (szs uf) i
    szj <- readArray (szs uf) j
    if szi < szj
        then do
            writeArray (ids uf) i j
            writeArray (szs uf) j (szi + szj)
        else do
            writeArray (ids uf) j i
            writeArray (szs uf) i (szj + szi)

--  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --

getInt1 :: IO Int
getInt1 = readInt1 <$> BS.getLine

getInt2 :: IO (Int, Int)
getInt2 = readInt2 <$> BS.getLine

getInt3 :: IO (Int, Int, Int)
getInt3 = readInt3 <$> BS.getLine

getInts :: IO [Int]
getInts = readInts <$> BS.getLine

getIntN :: Int -> IO [Int]
getIntN n = map readInt1 <$> replicateM n BS.getLine

format :: Show a => Maybe a -> IO ()
format Nothing = putStrLn "NO"
format (Just a) = putStrLn "YES" >> print a

-- [1,2,3] -> 1 2 3
putInts :: [Int] -> IO ()
-- putInts [] = return ()
-- putInts xs = BL.putStrLn . toLazyByteString . foldl1 mappend . intersperse (char8 ' ') $ map intDec xs
putInts = putStrLn . unwords . map show

readInt1 :: BS.ByteString -> Int
readInt1 = fst . fromJust . BS.readInt

readInt2 :: BS.ByteString -> (Int,Int)
readInt2 = toTuple . readInts

readInt3 :: BS.ByteString -> (Int,Int,Int)
readInt3 = toTriple . readInts

readInts :: BS.ByteString -> [Int]
readInts =  map readInt1 . BS.words

readInt641 :: BS.ByteString -> Int64
readInt641 = fromIntegral . fst . fromJust . BS.readInteger

readInt642 :: BS.ByteString -> (Int64,Int64)
readInt642 = toTuple . readInt64s

readInt643 :: BS.ByteString -> (Int64,Int64,Int64)
readInt643 = toTriple . readInt64s

readInt64s :: BS.ByteString -> [Int64]
readInt64s =  map readInt641 . BS.words

readInteger1 :: BS.ByteString -> Integer
readInteger1 = fst . fromJust . BS.readInteger

readInteger2 :: BS.ByteString -> (Integer,Integer)
readInteger2 = toTuple . readIntegers

readInteger3 :: BS.ByteString -> (Integer,Integer,Integer)
readInteger3 = toTriple . readIntegers

readIntegers :: BS.ByteString -> [Integer]
readIntegers =  map readInteger1 . BS.words

toTuple :: [a] -> (a, a)
toTuple [x, y] = (x, y)

toTriple :: [a] -> (a, a, a)
toTriple [x, y, z] =(x, y, z)

fromTuple :: (a, a) -> [a]
fromTuple (x, y) = [x, y]

fromTriple :: (a, a, a) -> [a]
fromTriple (x, y, z) = [x, y, z]

-- if not applying, use "id"

applyTuple :: (a -> a') -> (b -> b') -> (a, b) -> (a', b')
applyTuple f g (x, y) = (f x, g y)

applyTriple :: (a -> a') -> (b -> b') -> (c -> c') -> (a, b, c) -> (a', b', c')
applyTriple f g h (x, y, z) = (f x, g y, h z)

-- @since 4.8.0.0
sortOn' :: Ord b => (a -> b) -> [a] -> [a]
sortOn' f =
  map snd . sortBy (comparing fst) . map (\x -> let y = f x in y `seq` (y, x))