import sys

input = sys.stdin.readline



class UnionFind():

    def __init__(self, n):

        self.n = n

        self.parents = [-1] * n

    def find(self, x):

        if self.parents[x] < 0:

            return x

        else:

            self.parents[x] = self.find(self.parents[x])

            return self.parents[x]

    def union(self, x, y):

        x = self.find(x)

        y = self.find(y)

        if x == y:

            return

        if self.parents[x] > self.parents[y]:

            x, y = y, x

        self.parents[x] += self.parents[y]

        self.parents[y] = x

    def size(self, x):

        return -self.parents[self.find(x)]

    def same(self, x, y):

        return self.find(x) == self.find(y)



N = int(eval(input()))

town = [list(map(int,input().split()))+[i] for i in range(N)]



townx = sorted(town)

towny = sorted(town,key = lambda t : t[1])



road = []



for i in range(N-1):

    road.append([abs(townx[i][0]-townx[i+1][0]),townx[i][2],townx[i+1][2]])

    road.append([abs(towny[i][1]-towny[i+1][1]),towny[i][2],towny[i+1][2]])



road.sort()



uf = UnionFind(N)

ans = 0



for r in road:

    cost,t1,t2 = r

    if uf.same(t1,t2):

        continue

    uf.union(t1,t2)

    ans += cost

    

print(ans)
class Graph():  #non-directed

    def __init__(self, n, edge, indexed=1):

        self.n = n

        self.edge = edge

        self.indexed = indexed

        self.graph = [[] for _ in range(n)]

        for e in edge:

            self.graph[e[0] - indexed].append((e[1] - indexed, e[2]))

            self.graph[e[1] - indexed].append((e[0] - indexed, e[2]))



    def kruskal(self):  #UnionFind

        edgemap = {self.edge[i]: i for i in range(len(self.edge))}

        sortedge = sorted(self.edge, key=lambda x: x[2])

        #sortedge = reversed(sortedge) コストの最大化

        uf = UnionFind(self.n)

        res = 0

        restored = []

        for e in sortedge:

            if uf.find(e[0] - self.indexed) != uf.find(e[1] - self.indexed):

                res += e[2]

                restored.append(edgemap[e])

                uf.unite(e[0] - self.indexed, e[1] - self.indexed)

        return res, restored



class UnionFind():

    def __init__(self, n):

        self.n = n

        self.parents = [i for i in range(n)]

        self.rank = [0 for _ in range(n)]

        self.size = [1 for _ in range(n)]



    def find(self, x):

        root = x

        while self.parents[root] != root:

            root = self.parents[root]

        while self.parents[x] != root:

            parent = self.parents[x]

            self.parents[x] = root

            x = parent

        return root



    def unite(self, x, y):

        xroot = self.find(x)

        yroot = self.find(y)

        if xroot == yroot: return

        xrank = self.rank[xroot]

        yrank = self.rank[yroot]

        if xrank < yrank:

            self.parents[xroot] = yroot

            self.size[yroot] += self.size[xroot]

        elif xrank == yrank:

            self.parents[yroot] = xroot

            self.rank[yroot] += 1

            self.size[xroot] += self.size[yroot]

        else:

            self.parents[yroot] = xroot

            self.size[xroot] += self.size[yroot]



import sys

input = sys.stdin.readline



N = int(eval(input()))

T = []



for i in range(N):

    x, y = list(map(int, input().split()))

    T.append((x, y, i))



sort_by_x = sorted(T, key=lambda x: x[0])

sort_by_y = sorted(T, key=lambda x: x[1])



E = []



for i in range(N - 1):

    x1, y1, id1 = sort_by_x[i]

    x2, y2 ,id2 = sort_by_x[i + 1]

    E.append((id1, id2, min(abs(x1 - x2), abs(y1 - y2))))

    x1, y1, id1 = sort_by_y[i]

    x2, y2 ,id2 = sort_by_y[i + 1]

    E.append((id1, id2, min(abs(x1 - x2), abs(y1 - y2))))



g = Graph(N, E)



print((g.kruskal()[0]))
import sys

input = sys.stdin.readline


class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        if self.parents[x] > self.parents[y]:
            x, y = y, x
        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

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


N = int(eval(input()))
town = [list(map(int, input().split())) + [i] for i in range(N)]
townx = sorted(town)
towny = sorted(town, key=lambda t: t[1])
road = []
for i in range(N - 1):
    road.append([abs(townx[i][0] - townx[i + 1][0]), townx[i][2], townx[i + 1][2]])
    road.append([abs(towny[i][1] - towny[i + 1][1]), towny[i][2], towny[i + 1][2]])
road.sort()
uf = UnionFind(N)
ans = 0
for r in road:
    cost, t1, t2 = r
    if uf.same(t1, t2):
        continue
    uf.union(t1, t2)
    ans += cost
print(ans)

class Graph:  # non-directed
    def __init__(self, n, edge, indexed=1):
        self.n = n
        self.edge = edge
        self.indexed = indexed
        self.graph = [[] for _ in range(n)]
        for e in edge:
            self.graph[e[0] - indexed].append((e[1] - indexed, e[2]))
            self.graph[e[1] - indexed].append((e[0] - indexed, e[2]))

    def kruskal(self):  # UnionFind
        edgemap = {self.edge[i]: i for i in range(len(self.edge))}
        sortedge = sorted(self.edge, key=lambda x: x[2])
        # sortedge = reversed(sortedge) コストの最大化
        uf = UnionFind(self.n)
        res = 0
        restored = []
        for e in sortedge:
            if uf.find(e[0] - self.indexed) != uf.find(e[1] - self.indexed):
                res += e[2]
                restored.append(edgemap[e])
                uf.unite(e[0] - self.indexed, e[1] - self.indexed)
        return res, restored


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

    def find(self, x):
        root = x
        while self.parents[root] != root:
            root = self.parents[root]
        while self.parents[x] != root:
            parent = self.parents[x]
            self.parents[x] = root
            x = parent
        return root

    def unite(self, x, y):
        xroot = self.find(x)
        yroot = self.find(y)
        if xroot == yroot:
            return
        xrank = self.rank[xroot]
        yrank = self.rank[yroot]
        if xrank < yrank:
            self.parents[xroot] = yroot
            self.size[yroot] += self.size[xroot]
        elif xrank == yrank:
            self.parents[yroot] = xroot
            self.rank[yroot] += 1
            self.size[xroot] += self.size[yroot]
        else:
            self.parents[yroot] = xroot
            self.size[xroot] += self.size[yroot]


import sys

input = sys.stdin.readline
N = int(eval(input()))
T = []
for i in range(N):
    x, y = list(map(int, input().split()))
    T.append((x, y, i))
sort_by_x = sorted(T, key=lambda x: x[0])
sort_by_y = sorted(T, key=lambda x: x[1])
E = []
for i in range(N - 1):
    x1, y1, id1 = sort_by_x[i]
    x2, y2, id2 = sort_by_x[i + 1]
    E.append((id1, id2, min(abs(x1 - x2), abs(y1 - y2))))
    x1, y1, id1 = sort_by_y[i]
    x2, y2, id2 = sort_by_y[i + 1]
    E.append((id1, id2, min(abs(x1 - x2), abs(y1 - y2))))
g = Graph(N, E)
print((g.kruskal()[0]))

-import sys +class Graph:  # non-directed +    def __init__(self, n, edge, indexed=1): +        self.n = n +        self.edge = edge +        self.indexed = indexed +        self.graph = [[] for _ in range(n)] +        for e in edge: +            self.graph[e[0] - indexed].append((e[1] - indexed, e[2])) +            self.graph[e[1] - indexed].append((e[0] - indexed, e[2])) -input = sys.stdin.readline +    def kruskal(self):  # UnionFind +        edgemap = {self.edge[i]: i for i in range(len(self.edge))} +        sortedge = sorted(self.edge, key=lambda x: x[2]) +        # sortedge = reversed(sortedge) コストの最大化 +        uf = UnionFind(self.n) +        res = 0 +        restored = [] +        for e in sortedge: +            if uf.find(e[0] - self.indexed) != uf.find(e[1] - self.indexed): +                res += e[2] +                restored.append(edgemap[e]) +                uf.unite(e[0] - self.indexed, e[1] - self.indexed) +        return res, restored -        self.parents = [-1] * n +        self.parents = [i for i in range(n)] +        self.rank = [0 for _ in range(n)] +        self.size = [1 for _ in range(n)] -        if self.parents[x] < 0: -            return x +        root = x +        while self.parents[root] != root: +            root = self.parents[root] +        while self.parents[x] != root: +            parent = self.parents[x] +            self.parents[x] = root +            x = parent +        return root + +    def unite(self, x, y): +        xroot = self.find(x) +        yroot = self.find(y) +        if xroot == yroot: +            return +        xrank = self.rank[xroot] +        yrank = self.rank[yroot] +        if xrank < yrank: +            self.parents[xroot] = yroot +            self.size[yroot] += self.size[xroot] +        elif xrank == yrank: +            self.parents[yroot] = xroot +            self.rank[yroot] += 1 +            self.size[xroot] += self.size[yroot] -            self.parents[x] = self.find(self.parents[x]) -            return self.parents[x] - -    def union(self, x, y): -        x = self.find(x) -        y = self.find(y) -        if x == y: -            return -        if self.parents[x] > self.parents[y]: -            x, y = y, x -        self.parents[x] += self.parents[y] -        self.parents[y] = x - -    def size(self, x): -        return -self.parents[self.find(x)] - -    def same(self, x, y): -        return self.find(x) == self.find(y) +            self.parents[yroot] = xroot +            self.size[xroot] += self.size[yroot] +import sys + +input = sys.stdin.readline -town = [list(map(int, input().split())) + [i] for i in range(N)] -townx = sorted(town) -towny = sorted(town, key=lambda t: t[1]) -road = [] +T = [] +for i in range(N): +    x, y = list(map(int, input().split())) +    T.append((x, y, i)) +sort_by_x = sorted(T, key=lambda x: x[0]) +sort_by_y = sorted(T, key=lambda x: x[1]) +E = [] -    road.append([abs(townx[i][0] - townx[i + 1][0]), townx[i][2], townx[i + 1][2]]) -    road.append([abs(towny[i][1] - towny[i + 1][1]), towny[i][2], towny[i + 1][2]]) -road.sort() -uf = UnionFind(N) -ans = 0 -for r in road: -    cost, t1, t2 = r -    if uf.same(t1, t2): -        continue -    uf.union(t1, t2) -    ans += cost -print(ans) +    x1, y1, id1 = sort_by_x[i] +    x2, y2, id2 = sort_by_x[i + 1] +    E.append((id1, id2, min(abs(x1 - x2), abs(y1 - y2)))) +    x1, y1, id1 = sort_by_y[i] +    x2, y2, id2 = sort_by_y[i + 1] +    E.append((id1, id2, min(abs(x1 - x2), abs(y1 - y2)))) +g = Graph(N, E) +print((g.kruskal()[0]))