
import java.util.Scanner

import scala.annotation.tailrec
import scala.math._

object Main extends App{
  val sc = new Scanner(System.in)

  val n = sc.nextInt()
  val ps = Range(0, n).map(i => (i, sc.nextInt, sc.nextInt))
    .toArray

  val uf = new IUnionFind(n)

  val ans = Stream.concat(edges(ps.clone(), (a, b) => a._2 > b._2), edges(ps.clone(), (a, b) => a._3 > b._3))
    .sortWith((a, b) => a._3 < b._3)
    .foldLeft(0)((sum, tuple) => {
//      println(s"$tuple $sum ${uf.connected(tuple._1, tuple._2)}")
      uf.connected(tuple._1, tuple._2) match {
      case true =>
        sum
      case _ =>
        uf.union(tuple._1, tuple._2)
        sum + tuple._3
      }})

  println(ans)

  def edges(ar: Array[(Int, Int, Int)], f: ((Int, Int, Int), (Int, Int, Int)) => Boolean): Stream[(Int, Int, Int)] = {
    val sorted = ar.sortWith(f)
    Range(0, ar.length -1).map(i => (sorted(i)._1, sorted(i + 1)._1, min(abs(sorted(i)._2 - sorted(i + 1)._2), abs(sorted(i)._3 - sorted(i + 1)._3)))).toStream
  }
}

class IUnionFind(val size: Int) {

  private case class Node(var parent: Option[Int], var treeSize: Int)

  private val nodes = Array.fill[Node](size)(new Node(None, 1))

  def union(t1: Int, t2: Int): IUnionFind = {
    if (t1 == t2) return this

    val root1 = root(t1)
    val root2 = root(t2)
    if (root1 == root2) return this

    val node1 = nodes(root1)
    val node2 = nodes(root2)

    if (node1.treeSize < node2.treeSize) {
      node1.parent = Some(t2)
      node2.treeSize += node1.treeSize
    } else {
      node2.parent = Some(t1)
      node1.treeSize += node2.treeSize
    }
    this
  }

  def connected(t1: Int, t2: Int): Boolean = t1 == t2 || root(t1) == root(t2)

  @tailrec
  private def root(t: Int): Int = nodes(t).parent match {
    case None => t
    case Some(p) => root(p)
  }
}