### BUGGY CODE ###

#### import ####
import sys
import math
from collections import defaultdict

#### 設定 ####
sys.setrecursionlimit(10**7)
def input():
  return sys.stdin.readline()[:-1]

#### 定数 ####
mod = 10**9 + 7

#### 読み込み ####
def I(): return int(input())
def II(): return map(int, input().split())
def III(): return list(map(int, input().split()))
def Line(N):
  read_all = [tuple(map(int, input().split())) for _ in range(N)]
  return map(list,zip(*read_all))

#################

class UF(object):
  def __init__(self, n=1):
    self.par = [i for i in range(n)]
    self.rank = [0 for _ in range(n)]
    self.size = [1 for _ in range(n)]

  def find(self, x):
    """
    x が属するグループを探索
    """
    if self.par[x] == x:
      return x
    else:
      self.par[x] = self.find(self.par[x])
      return self.par[x]

  def union(self, x, y):
    """
    x と y のグループを結合
    """
    x = self.find(x)
    y = self.find(y)
    if x != y:
      if self.rank[x] < self.rank[y]:
        x, y = y, x
      if self.rank[x] == self.rank[y]:
        self.rank[x] += 1
      self.par[y] = x
      self.size[x] += self.size[y]

  def is_same(self, x, y):
    """
    x と y が同じグループか否か
    """
    return self.find(x) == self.find(y)

  def get_size(self, x):
    """
    x が属するグループの要素数
    """
    x = self.find(x)
    return self.size[x]

N = I()
x = []
y = []

for i in range(N):
  xtemp,ytemp = II()
  x.append([xtemp, i])
  y.append([ytemp, i])

xsort = sorted(x)
ysort = sorted(y)

graph = []
for i in range(N-1):
  graph.append([min(abs(xsort[i][0]-xsort[i+1][0]),abs(y[xsort[i][1]][0]-y[xsort[i+1][1]][0])), \
                xsort[i][1],xsort[i+1][1]])
  graph.append([min(abs(ysort[i][0]-ysort[i+1][0]),abs(x[ysort[i][1]][0]-x[ysort[i+1][1]][0])), \
                ysort[i][1],ysort[i+1][1]])

ans = 0
uf = UF(N)
graph.sort()
for w in graph:
  if not uf.is_same(w[1],w[2]):
    uf.union(w[1],w[2])
    ans += w[0]

print(ans)

### FIXED CODE ###

#### import ####
import sys
import math
from collections import defaultdict

#### 設定 ####
sys.setrecursionlimit(10**7)
def input():
  return sys.stdin.readline()[:-1]

#### 定数 ####
mod = 10**9 + 7

#### 読み込み ####
def I(): return int(input())
def II(): return map(int, input().split())
def III(): return list(map(int, input().split()))
def Line(N):
  read_all = [tuple(map(int, input().split())) for _ in range(N)]
  return map(list,zip(*read_all))

#################

class UF(object):
  def __init__(self, n=1):
    self.par = [i for i in range(n)]
    self.rank = [0 for _ in range(n)]
    self.size = [1 for _ in range(n)]

  def find(self, x):
    """
    x が属するグループを探索
    """
    if self.par[x] == x:
      return x
    else:
      self.par[x] = self.find(self.par[x])
      return self.par[x]

  def union(self, x, y):
    """
    x と y のグループを結合
    """
    x = self.find(x)
    y = self.find(y)
    if x != y:
      if self.rank[x] < self.rank[y]:
        x, y = y, x
      if self.rank[x] == self.rank[y]:
        self.rank[x] += 1
      self.par[y] = x
      self.size[x] += self.size[y]

  def is_same(self, x, y):
    """
    x と y が同じグループか否か
    """
    return self.find(x) == self.find(y)

  def get_size(self, x):
    """
    x が属するグループの要素数
    """
    x = self.find(x)
    return self.size[x]

N = I()
x = []
y = []

for i in range(N):
  xtemp,ytemp = II()
  x.append([xtemp, i])
  y.append([ytemp, i])

xsort = sorted(x,lambda a:a[0])
ysort = sorted(y,lambda a:a[0])

graph = []
for i in range(N-1):
  graph.append([min(abs(xsort[i][0]-xsort[i+1][0]),abs(y[xsort[i][1]][0]-y[xsort[i+1][1]][0])), \
                xsort[i][1],xsort[i+1][1]])
  graph.append([min(abs(ysort[i][0]-ysort[i+1][0]),abs(x[ysort[i][1]][0]-x[ysort[i+1][1]][0])), \
                ysort[i][1],ysort[i+1][1]])

ans = 0
uf = UF(N)
graph.sort()
for w in graph:
  if not uf.is_same(w[1],w[2]):
    uf.union(w[1],w[2])
    ans += w[0]

print(ans)