object Main extends App {
  val sc = new FastScanner(System.in)
  val n = sc.nextInt()
  val xy = List.fill(n)((sc.nextInt(), sc.nextInt())).zipWithIndex
  val e = xy.sortBy(_._1._1).sliding(2).filter{
    case List((p1, _), (p2, _)) => (p1._1 - p2._1).abs <= (p1._2 - p2._2).abs
  }.map{
    case List((p1, idx1), (p2, idx2)) => (idx1, idx2, (p1._1 - p2._1).abs)
  } ++ xy.sortBy(_._1._2).sliding(2).filter{
    case List((p1, _), (p2, _)) => (p1._2 - p2._2).abs <= (p1._1 - p2._1).abs
  }.map{
    case List((p1, idx1), (p2, idx2)) => (idx1, idx2, (p1._2 - p2._2).abs)
  }

  def minimumSpanningTree(n: Int, edges: Seq[(Int, Int, Int)]): Int = {
    class UnionFindTree(n: Int) {
      private val par = Array.tabulate(n)(identity)
      private val rank = Array.fill(n)(1)

      def root(x: Int): Int = {
        var res = x
        var children = List[Int]()
        while (par(res) != res) {
          children ::= res
          res = par(res)
        }

        for (y <- children) {
          par(y) = res
        }
        res
      }

      def unite(x: Int, y: Int): Unit = {
        val xr = root(x)
        val yr = root(y)
        if (xr != yr) {
          if (rank(xr) < rank(yr)) {
            par(xr) = yr
          } else {
            par(yr) = xr
            if (rank(xr) == rank(yr)) {
              rank(xr) += 1
            }
          }
        }
      }
    }

    val uft = new UnionFindTree(n)
    var ans = 0
    for ((x, y, c) <- edges.sortBy(_._3) if uft.root(x) != uft.root(y)) {
      uft.unite(x, y)
      ans += c
    }

    ans
  }

  println(minimumSpanningTree(n, e.toList))
}

class FastScanner(source: java.io.InputStream) {
  val buf = new Array[Byte](1024)
  var now, end = 0

  def isPrintable(b: Byte): Boolean = 33 <= b && b <= 126
  def isNum(b: Byte): Boolean = 48 <= b && b <= 57

  def hasNextByte: Boolean = {
    if (now < end) {
      true
    } else {
      now = 0
      end = source.read(buf)
      end > 0
    }
  }

  def nextByte(): Byte = {
    if (hasNextByte) {
      val b = buf(now)
      now += 1
      b
    } else {
      -1
    }
  }

  def hasNext: Boolean = {
    while (hasNextByte && !isPrintable(buf(now))) {
      now += 1
    }
    hasNextByte
  }

  def next(): String = {
    if (hasNext) {
      val sb = new StringBuilder()
      var b = nextByte()
      while (isPrintable(b)) {
        sb += b.toChar
        b = nextByte()
      }
      sb.toString
    } else {
      throw new NoSuchElementException()
    }
  }

  def nextInt(): Int = {
    nextLong().toInt
  }

  def nextLong(): Long = {
    if (hasNext) {
      var b = nextByte()
      var sign = 1
      var n = 0L
      if (b == '-') {
        sign = -1
        b = nextByte()
      }
      while (isNum(b)) {
        n = n * 10 + (b - 48)
        b = nextByte()
      }
      sign * n
    } else {
      throw new NoSuchElementException()
    }
  }

  def nextDouble(): Double = next().toDouble
}
