import sys

sys.setrecursionlimit(2147483647)

INF=float("inf")

MOD=10**9+7

# input=lambda :sys.stdin.readline().rstrip()

def resolve():

    class UnionFind(object):

        """

        query: O(Ack^-1(n,n)) (amortize)

        """

        def __init__(self,n):

            """

            param n: number of nodes

            """

            self.__par=list(range(n))

            self.__rank=[0]*n

            self.__size=[1]*n



        def __root(self,k):

            if self.__par[k]==k: return k

            else:

                self.__par[k]=self.__root(self.__par[k])

                return self.__par[k]



        def is_same(self,i,j):

            return self.__root(i)==self.__root(j)



        def unite(self,i,j):

            i=self.__root(i)

            j=self.__root(j)

            if i==j: return

            if self.__rank[i]>self.__rank[j]:

                self.__par[j]=i

            else:

                self.__par[i]=j

                if self.__rank[i]==self.__rank[j]: self.__rank[j]+=1



    # 候補となるedgesは2N-2個しかないため、全列挙

    # Kruskal's algorithmでuniteしていく

    from operator import itemgetter

    n=int(eval(input()))

    P=[0]*n

    edges=[0]*(2*n-2)

    for i in range(n):

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

        P[i]=(x,y,i)

    # xでsort

    P.sort(key=itemgetter(0))

    for k in range(n-1):

        x0,y0,i=P[k]

        x1,y1,j=P[k+1]

        edges[k]=(i,j,min(abs(x0-x1),abs(y0-y1)))

    # yでsort

    P.sort(key=itemgetter(1))

    for k in range(n-1):

        x0,y0,i=P[k]

        x1,y1,j=P[k+1]

        edges[k+n-1]=(i,j,min(abs(x0-x1),abs(y0-y1)))

    # edgesをcostでsort

    edges.sort(key=itemgetter(2))

    # union findに突っ込んでいく

    tree=UnionFind(n)

    ans=0

    for i,j,cost in edges:

        if tree.is_same(i,j): continue

        tree.unite(i,j)

        ans+=cost

    print(ans)



resolve()
import sys

sys.setrecursionlimit(2147483647)

INF=float("inf")

MOD=10**9+7

input=lambda :sys.stdin.readline().rstrip()

def resolve():

    class UnionFind(object):

        """

        query: O(Ack^-1(n,n)) (amortize)

        """

        def __init__(self,n):

            """

            param n: number of nodes

            """

            self.__par=list(range(n))

            self.__rank=[0]*n

            self.__size=[1]*n



        def __root(self,k):

            if self.__par[k]==k: return k

            else:

                self.__par[k]=self.__root(self.__par[k])

                return self.__par[k]



        def is_same(self,i,j):

            return self.__root(i)==self.__root(j)



        def unite(self,i,j):

            i=self.__root(i)

            j=self.__root(j)

            if i==j: return

            if self.__rank[i]>self.__rank[j]:

                self.__par[j]=i

            else:

                self.__par[i]=j

                if self.__rank[i]==self.__rank[j]: self.__rank[j]+=1



    # Kruskal's algorithm

    from operator import itemgetter

    n=int(eval(input()))

    P=[0]*n

    edges=[0]*(2*n-2)

    for i in range(n):

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

        P[i]=(x,y,i)

    # xでsort

    P.sort(key=itemgetter(0))

    for k in range(n-1):

        x0,y0,i=P[k]

        x1,y1,j=P[k+1]

        edges[k]=(i,j,min(abs(x0-x1),abs(y0-y1)))

    # yでsort

    P.sort(key=itemgetter(1))

    for k in range(n-1):

        x0,y0,i=P[k]

        x1,y1,j=P[k+1]

        edges[k+n-1]=(i,j,min(abs(x0-x1),abs(y0-y1)))

    # edgesをcostでsort

    edges.sort(key=itemgetter(2))

    # union findに突っ込んでいく

    tree=UnionFind(n)

    ans=0

    for i,j,cost in edges:

        if tree.is_same(i,j): continue

        tree.unite(i,j)

        ans+=cost

    print(ans)

resolve()
import sys

sys.setrecursionlimit(2147483647)
INF = float("inf")
MOD = 10**9 + 7
# input=lambda :sys.stdin.readline().rstrip()
def resolve():
    class UnionFind(object):
        """
        query: O(Ack^-1(n,n)) (amortize)
        """

        def __init__(self, n):
            """
            param n: number of nodes
            """
            self.__par = list(range(n))
            self.__rank = [0] * n
            self.__size = [1] * n

        def __root(self, k):
            if self.__par[k] == k:
                return k
            else:
                self.__par[k] = self.__root(self.__par[k])
                return self.__par[k]

        def is_same(self, i, j):
            return self.__root(i) == self.__root(j)

        def unite(self, i, j):
            i = self.__root(i)
            j = self.__root(j)
            if i == j:
                return
            if self.__rank[i] > self.__rank[j]:
                self.__par[j] = i
            else:
                self.__par[i] = j
                if self.__rank[i] == self.__rank[j]:
                    self.__rank[j] += 1

    # 候補となるedgesは2N-2個しかないため、全列挙
    # Kruskal's algorithmでuniteしていく
    from operator import itemgetter

    n = int(eval(input()))
    P = [0] * n
    edges = [0] * (2 * n - 2)
    for i in range(n):
        x, y = list(map(int, input().split()))
        P[i] = (x, y, i)
    # xでsort
    P.sort(key=itemgetter(0))
    for k in range(n - 1):
        x0, y0, i = P[k]
        x1, y1, j = P[k + 1]
        edges[k] = (i, j, min(abs(x0 - x1), abs(y0 - y1)))
    # yでsort
    P.sort(key=itemgetter(1))
    for k in range(n - 1):
        x0, y0, i = P[k]
        x1, y1, j = P[k + 1]
        edges[k + n - 1] = (i, j, min(abs(x0 - x1), abs(y0 - y1)))
    # edgesをcostでsort
    edges.sort(key=itemgetter(2))
    # union findに突っ込んでいく
    tree = UnionFind(n)
    ans = 0
    for i, j, cost in edges:
        if tree.is_same(i, j):
            continue
        tree.unite(i, j)
        ans += cost
    print(ans)


resolve()

import sys

sys.setrecursionlimit(2147483647)
INF = float("inf")
MOD = 10**9 + 7
input = lambda: sys.stdin.readline().rstrip()


def resolve():
    class UnionFind(object):
        """
        query: O(Ack^-1(n,n)) (amortize)
        """

        def __init__(self, n):
            """
            param n: number of nodes
            """
            self.__par = list(range(n))
            self.__rank = [0] * n
            self.__size = [1] * n

        def __root(self, k):
            if self.__par[k] == k:
                return k
            else:
                self.__par[k] = self.__root(self.__par[k])
                return self.__par[k]

        def is_same(self, i, j):
            return self.__root(i) == self.__root(j)

        def unite(self, i, j):
            i = self.__root(i)
            j = self.__root(j)
            if i == j:
                return
            if self.__rank[i] > self.__rank[j]:
                self.__par[j] = i
            else:
                self.__par[i] = j
                if self.__rank[i] == self.__rank[j]:
                    self.__rank[j] += 1

    # Kruskal's algorithm
    from operator import itemgetter

    n = int(eval(input()))
    P = [0] * n
    edges = [0] * (2 * n - 2)
    for i in range(n):
        x, y = list(map(int, input().split()))
        P[i] = (x, y, i)
    # xでsort
    P.sort(key=itemgetter(0))
    for k in range(n - 1):
        x0, y0, i = P[k]
        x1, y1, j = P[k + 1]
        edges[k] = (i, j, min(abs(x0 - x1), abs(y0 - y1)))
    # yでsort
    P.sort(key=itemgetter(1))
    for k in range(n - 1):
        x0, y0, i = P[k]
        x1, y1, j = P[k + 1]
        edges[k + n - 1] = (i, j, min(abs(x0 - x1), abs(y0 - y1)))
    # edgesをcostでsort
    edges.sort(key=itemgetter(2))
    # union findに突っ込んでいく
    tree = UnionFind(n)
    ans = 0
    for i, j, cost in edges:
        if tree.is_same(i, j):
            continue
        tree.unite(i, j)
        ans += cost
    print(ans)


resolve()

-# input=lambda :sys.stdin.readline().rstrip() +input = lambda: sys.stdin.readline().rstrip() + + -    # 候補となるedgesは2N-2個しかないため、全列挙 -    # Kruskal's algorithmでuniteしていく +    # Kruskal's algorithm