'''

https://atcoder.jp/contests/abc065/tasks/arc076_b

最小全域木を考える際にある頂点について他の頂点への最小コストを

考えて繋げていくのは間違い(全域木になる保証がない)

考えたいのはあくまでも全辺のコスト



今回はxとyでそれぞれソートして隣り合う2点のコストのみを考えれば良い

'''

def main():

    import sys

    input = sys.stdin.readline

    sys.setrecursionlimit(10000000)

    from collections import Counter, deque

    #from collections import defaultdict

    from itertools import combinations, permutations, accumulate

    #from itertools import product

    from bisect import bisect_left,bisect_right

    import heapq

    from math import floor, ceil

    #from operator import itemgetter



    #inf = 10**17

    #mod = 1000000007



    N = int(eval(input()))

    xy = []

    for i in range(N):

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

        xy.append([x, y, i])

    x_sort = sorted(xy, key=lambda x: x[0])

    y_sort = sorted(xy, key=lambda x: x[1])



    #[cost, 頂点1, 頂点2]

    cost = []

    for i in range(N-1):

        cost.append([abs(x_sort[i][0]-x_sort[i+1][0]), x_sort[i][2], x_sort[i+1][2]])

        cost.append([abs(y_sort[i][1]-y_sort[i+1][1]), y_sort[i][2], y_sort[i+1][2]])

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



    def find(x):

        if par[x] < 0:

            return x

        else:

            par[x] = find(par[x])

            return par[x]

    

    def unite(x,y):

        x = find(x)

        y = find(y)

        if x == y:

            return False

        else:

            if par[x] > par[y]:

                x,y = y,x

            par[x] += par[y]

            par[y] = x

            return True

    

    def same(x,y):

        return find(x) == find(y)



    par = [-1]*N



    res = 0

    for c, v1, v2 in cost:

        if not same(v1, v2):

            unite(v1, v2)

            res += c

    print(res)





if __name__ == '__main__':

    main()
def main():

    import sys

    input = sys.stdin.readline

    sys.setrecursionlimit(10000000)

    from collections import Counter, deque

    #from collections import defaultdict

    from itertools import combinations, permutations, accumulate

    #from itertools import product

    from bisect import bisect_left,bisect_right

    import heapq

    from math import floor, ceil

    #from operator import itemgetter



    #inf = 10**17

    #mod = 1000000007



    N = int(eval(input()))

    xy = []

    for i in range(N):

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

        xy.append([x, y, i])

    x_sort = sorted(xy, key=lambda x: x[0])

    y_sort = sorted(xy, key=lambda x: x[1])



    #[cost, 頂点1, 頂点2]

    cost = []

    for i in range(N-1):

        cost.append([x_sort[i+1][0]-x_sort[i][0], x_sort[i][2], x_sort[i+1][2]])

        cost.append([y_sort[i+1][1]-y_sort[i][1], y_sort[i][2], y_sort[i+1][2]])

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



    def find(x):

        if par[x] < 0:

            return x

        else:

            par[x] = find(par[x])

            return par[x]

    

    def unite(x,y):

        x = find(x)

        y = find(y)

        if x == y:

            return False

        else:

            if par[x] > par[y]:

                x,y = y,x

            par[x] += par[y]

            par[y] = x

            return True

    

    def same(x,y):

        return find(x) == find(y)



    par = [-1]*N



    res = 0

    for c, v1, v2 in cost:

        if not same(v1, v2):

            unite(v1, v2)

            res += c

    print(res)





if __name__ == '__main__':

    main()
"""
https://atcoder.jp/contests/abc065/tasks/arc076_b
最小全域木を考える際にある頂点について他の頂点への最小コストを
考えて繋げていくのは間違い(全域木になる保証がない)
考えたいのはあくまでも全辺のコスト
今回はxとyでそれぞれソートして隣り合う2点のコストのみを考えれば良い
"""


def main():
    import sys

    input = sys.stdin.readline
    sys.setrecursionlimit(10000000)
    from collections import Counter, deque

    # from collections import defaultdict
    from itertools import combinations, permutations, accumulate

    # from itertools import product
    from bisect import bisect_left, bisect_right
    import heapq
    from math import floor, ceil

    # from operator import itemgetter
    # inf = 10**17
    # mod = 1000000007
    N = int(eval(input()))
    xy = []
    for i in range(N):
        x, y = list(map(int, input().split()))
        xy.append([x, y, i])
    x_sort = sorted(xy, key=lambda x: x[0])
    y_sort = sorted(xy, key=lambda x: x[1])
    # [cost, 頂点1, 頂点2]
    cost = []
    for i in range(N - 1):
        cost.append(
            [abs(x_sort[i][0] - x_sort[i + 1][0]), x_sort[i][2], x_sort[i + 1][2]]
        )
        cost.append(
            [abs(y_sort[i][1] - y_sort[i + 1][1]), y_sort[i][2], y_sort[i + 1][2]]
        )
    cost = sorted(cost, key=lambda x: x[0])

    def find(x):
        if par[x] < 0:
            return x
        else:
            par[x] = find(par[x])
            return par[x]

    def unite(x, y):
        x = find(x)
        y = find(y)
        if x == y:
            return False
        else:
            if par[x] > par[y]:
                x, y = y, x
            par[x] += par[y]
            par[y] = x
            return True

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

    par = [-1] * N
    res = 0
    for c, v1, v2 in cost:
        if not same(v1, v2):
            unite(v1, v2)
            res += c
    print(res)


if __name__ == "__main__":
    main()

def main():
    import sys

    input = sys.stdin.readline
    sys.setrecursionlimit(10000000)
    from collections import Counter, deque

    # from collections import defaultdict
    from itertools import combinations, permutations, accumulate

    # from itertools import product
    from bisect import bisect_left, bisect_right
    import heapq
    from math import floor, ceil

    # from operator import itemgetter
    # inf = 10**17
    # mod = 1000000007
    N = int(eval(input()))
    xy = []
    for i in range(N):
        x, y = list(map(int, input().split()))
        xy.append([x, y, i])
    x_sort = sorted(xy, key=lambda x: x[0])
    y_sort = sorted(xy, key=lambda x: x[1])
    # [cost, 頂点1, 頂点2]
    cost = []
    for i in range(N - 1):
        cost.append([x_sort[i + 1][0] - x_sort[i][0], x_sort[i][2], x_sort[i + 1][2]])
        cost.append([y_sort[i + 1][1] - y_sort[i][1], y_sort[i][2], y_sort[i + 1][2]])
    cost = sorted(cost, key=lambda x: x[0])

    def find(x):
        if par[x] < 0:
            return x
        else:
            par[x] = find(par[x])
            return par[x]

    def unite(x, y):
        x = find(x)
        y = find(y)
        if x == y:
            return False
        else:
            if par[x] > par[y]:
                x, y = y, x
            par[x] += par[y]
            par[y] = x
            return True

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

    par = [-1] * N
    res = 0
    for c, v1, v2 in cost:
        if not same(v1, v2):
            unite(v1, v2)
            res += c
    print(res)


if __name__ == "__main__":
    main()

-""" -https://atcoder.jp/contests/abc065/tasks/arc076_b -最小全域木を考える際にある頂点について他の頂点への最小コストを -考えて繋げていくのは間違い(全域木になる保証がない) -考えたいのはあくまでも全辺のコスト -今回はxとyでそれぞれソートして隣り合う2点のコストのみを考えれば良い -""" - - -        cost.append( -            [abs(x_sort[i][0] - x_sort[i + 1][0]), x_sort[i][2], x_sort[i + 1][2]] -        ) -        cost.append( -            [abs(y_sort[i][1] - y_sort[i + 1][1]), y_sort[i][2], y_sort[i + 1][2]] -        ) +        cost.append([x_sort[i + 1][0] - x_sort[i][0], x_sort[i][2], x_sort[i + 1][2]]) +        cost.append([y_sort[i + 1][1] - y_sort[i][1], y_sort[i][2], y_sort[i + 1][2]])