from collections import defaultdict

class UnionFind:
    def __init__(self,N):
        self.parent = [i for i in range(N)]
        self.rank = [0] * N
        self.count = 0
    def root(self,a):
        if self.parent[a] == a:
            return a
        else:
            self.parent[a] = self.root(self.parent[a])
            return self.parent[a]
    def is_same(self,a,b):
        return self.root(a) == self.root(b)
    def unite(self,a,b):
        ra = self.root(a)
        rb = self.root(b)
        if ra == rb: return
        if self.rank[ra] < self.rank[rb]:
            self.parent[ra] = rb
        else:
            self.parent[rb] = ra
            if self.rank[ra] == self.rank[rb]: self.rank[ra] += 1
        self.count += 1

N = int(input())
xd = defaultdict(lambda: [])
yd = defaultdict(lambda: [])
for i in range(N):
    x,y = map(int,input().split())
    xd[x].append(i)
    yd[y].append(i)

uf = UnionFind(N)
es = []
pre_x = pre_i = None
for x,idxs in sorted(xd.items()):
    if len(idxs) >= 2:
        for i1,i2 in zip(idxs,idxs[1:]):
            if uf.is_same(i1,i2): continue
            uf.unite(i1,i2)
    if pre_x is not None:
        dx = x - pre_x
        es.append((dx,pre_i,idxs[0]))
    pre_x = x
    pre_i = idxs[0]
pre_y = pre_i = None
for y,idxs in sorted(yd.items()):
    if len(idxs) >= 2:
        for i1,i2 in zip(idxs,idxs[1:]):
            if uf.is_same(i1,i2): continue
            uf.unite(i1,i2)
    if pre_y is not None:
        dy = y - pre_y
        es.append((dy,pre_i,idxs[0]))
    pre_y = y
    pre_i = idxs[0]

if uf.count == N-1:
    print(0)
    exit()
ans = 0
for cost,a,b in sorted(es):
    if uf.is_same(a,b): continue
    uf.unite(a,b)
    ans += cost
    if uf.count == N-1:
        break
print(ans)