(* 配列版素集合データ構造 *)
module UnionFind : sig
  type t

  module Class : sig
    type t
    val compare : t -> t -> int
  end

  (* n要素の素集合データ構造を作る *)
  val make : int -> t
  (* 要素がどの集合に属するか調べる *)
  (* 要素は0からn-1の整数である必要がある *)
  val find : t -> int -> Class.t
  (* 与えられた集合同士を合併する *)
  (* 破壊的操作であるため注意 *)
  val unite : t -> Class.t -> Class.t -> unit
  (* 与えられた集合に属する要素の数を求める *)
  val cardinal : t -> Class.t -> int
end = struct
  type t = int array

  module Class = struct
    type t = int
    let compare = compare
  end

  let make n = Array.make n (-1)

  let rec find uf x =
    if uf.(x) < 0 then x
    else begin
      let y = find uf uf.(x) in
      uf.(x) <- y; y
    end

  let unite uf x y =
    if x <> y then begin
      let x, y = if uf.(x) <= uf.(y) then x, y else y, x in
      uf.(x) <- uf.(x) + uf.(y);
      uf.(y) <- x
    end

  let cardinal uf x = ~- (uf.(x))
end

module WeightedGraph
  (Weight : sig
    type t
    val compare : t -> t -> int
  end) :
sig
  type 'a church_list = { fold : 'b. ('a -> 'b -> 'b) -> 'b -> 'b }

  (*
   * HashtblやMapを用いているとプリム法と大差ない計算時間になってしまうため，
   * より汎用的な実装が欲しければそちらを当たること
   *)
  val kruskal :
    (* 頂点の数n *)
    int ->
    (* 辺のリスト *)
    (* 頂点は0からn-1までの整数でなくてはならない *)
    (int * int * Weight.t) church_list ->
    (* 最小全域木に含まれる辺のリスト
       畳み込む関数と初期値まで与えられて初めて計算を開始するので，
       最小全域木に対して色々な操作をしたい場合は，
       一度リストにして覚えておくとよい．
       最小全域木の重さの和だけ欲しいとか一回しか使わない場合は，
       直接畳み込む関数と初期値を与えるとdeforestationになっていい感じ． *)
    (int * int * Weight.t) church_list
end =
struct
  type 'a church_list = { fold : 'b. ('a -> 'b -> 'b) -> 'b -> 'b }

  let kruskal n es =
    { fold = fun f init ->
      let uf = UnionFind.make n in
      List.fold_left (fun acc (u, v, w) ->
        let c = UnionFind.find uf u in
        let d = UnionFind.find uf v in
        if UnionFind.Class.compare c d = 0
        then acc
        else (UnionFind.unite uf c d; f (u, v, w) acc)) init @@
      List.sort (fun (_, _, w) (_, _, w') -> Weight.compare w w') @@
      es.fold List.cons [] }
end
 
module Int = struct
  type t = int
  let compare = compare
end
 
module G = WeightedGraph (Int)
 
let () =
  let n = Scanf.scanf "%d\n" @@ fun n -> n in
  let xys = Array.to_list @@ Array.init n @@ fun i ->
    Scanf.scanf "%d %d\n" @@ fun x y -> x, y, i in
  let xedges =
    List.sort (fun (x, _, _) (x', _, _) -> compare x x') xys
    |> (fun ((x, y, i) :: xys) ->
        List.fold_left (fun (acc, x, y, i) (x', y', j) ->
          ((i, j, x' - x) :: acc, x', y', j)) ([], x, y, i) xys)
    |> (fun (acc, _, _, _) -> acc) in
  let yedges =
    List.sort (fun (_, y, _) (_, y', _) -> compare y y') xys
    |> (fun ((x, y, i) :: xys) ->
        List.fold_left (fun (acc, x, y, i) (x', y', j) ->
          ((i, j, y' - y) :: acc, x', y', j)) ([], x, y, i) xys)
    |> (fun (acc, _, _, _) -> acc) in
  Printf.printf "%d\n" @@
  (G.kruskal n { G.fold = fun f acc -> List.fold_right f xedges @@ List.fold_right f yedges acc }).G.fold (fun (_, _, d) -> ( + ) d) 0
