# Original solution
from itertools import accumulate
from math import*
from collections import deque
from collections import defaultdict
from itertools import permutations
from heapq import*
from collections import Counter
from itertools import*
from bisect import bisect_left,bisect_right
from copy import deepcopy
inf = 10**18
from functools import reduce

n = int(eval(input()))
xy = [[i] + list(map(int,input().split())) for i in range(n)]

xy.sort(key=lambda x:x[1])
edge  = []
for i in range(n-1):
    i1,x1,y1 = xy[i]
    i2,x2,y2 = xy[i+1]
    edge.append((x2-x1,i1,i2))

xy.sort(key=lambda x:x[2])
for i in range(n-1):
    i1,x1,y1 = xy[i]
    i2,x2,y2 = xy[i+1]
    edge.append((y2-y1,i1,i2))
class UnionFind():
    def __init__(self, N):
        self.rank = [0] * N
        self.par = [i for i in range(N)]
        self.counter = [1] * N

    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    def unite(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x != y:
            z = self.counter[x] + self.counter[y]
            self.counter[x], self.counter[y] = z, z
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
        else:
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    def size(self, x):
        x = self.find(x)
        return self.counter[x]

    def same(self, x, y):
        return self.find(x) == self.find(y)

#クラスカル法
uf = UnionFind(n)
edge.sort()
ans = 0
edge_cnt = 0
i = 0
while edge_cnt < n-1:
    cost,i1,i2 = edge[i]
    if not uf.same(i1,i2):
        ans += cost
        uf.unite(i1,i2)
        edge_cnt += 1
    i += 1
print(ans)

# Optimized solution
n = int(eval(input()))
xy = [[i] + list(map(int,input().split())) for i in range(n)]

xy.sort(key=lambda x:x[1])
edge  = []
for i in range(n-1):
    i1,x1,y1 = xy[i]
    i2,x2,y2 = xy[i+1]
    edge.append((x2-x1,i1,i2))

xy.sort(key=lambda x:x[2])
for i in range(n-1):
    i1,x1,y1 = xy[i]
    i2,x2,y2 = xy[i+1]
    edge.append((y2-y1,i1,i2))
class UnionFind():
    def __init__(self, N):
        self.rank = [0] * N
        self.par = [i for i in range(N)]
        self.counter = [1] * N

    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    def unite(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x != y:
            z = self.counter[x] + self.counter[y]
            self.counter[x], self.counter[y] = z, z
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
        else:
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    def size(self, x):
        x = self.find(x)
        return self.counter[x]

    def same(self, x, y):
        return self.find(x) == self.find(y)

#クラスカル法
uf = UnionFind(n)
edge.sort()
ans = 0
edge_cnt = 0
i = 0
while edge_cnt < n-1:
    cost,i1,i2 = edge[i]
    if not uf.same(i1,i2):
        ans += cost
        uf.unite(i1,i2)
        edge_cnt += 1
    i += 1
print(ans)