CodeEff/ECCO huggingface dataset:
# Original solution
N = int(eval(input()))

def find(x, U, r):
  p = []
  while not x == U[x]:
    p.append(x)
    x = U[x]
  for x_ in p:
    U[x_] == x
  return x
  
def merge(x, y, U, r):
  x = find(x, U, r)
  y = find(y, U, r)
  
  if x == y:
    return False
  #print(x,y, U)
  if r[x] < r[y]:
    x, y = y, x
  U[y] = x
  r[x] = max(r[y]+1, r[x])
  #print(x,y, U)
  return True
  
U = [i for i in range(N)]
r = [0 for _ in range(N)]

A = [(tuple(map(int, input().split())), j) for j in range(N)]
B = sorted(A)
C = sorted(A, key=lambda t: ((t[0][1],t[0][0]),t[1]))

#辺の作成
R = []
for i in range(1,N):
  c = B[i][0][0] - B[i-1][0][0]
  p1 = B[i][1]
  p2 = B[i-1][1]
  R.append((c, p1, p2))
  R.append((c, p2, p1))
  
  c = C[i][0][1] - C[i-1][0][1]
  p1 = C[i][1]
  p2 = C[i-1][1]
  R.append((c, p1, p2))
  R.append((c, p2, p1))
R.sort()

#Union Find:
U = [i for i in range(N)]
r = [0 for _ in range(N)]
#print(U)  
ans = 0
for road in R:
  c = road[0]
  x = road[1]
  y = road[2]
  if merge(x, y, U, r):
    #print(U)  
    ans += c
#print(U)    
print(ans)

# Optimized solution
N = int(eval(input()))

def find(x, U, r):
  p = []
  while not x == U[x]:
    p.append(x)
    x = U[x]
  for x_ in p:
    U[x_] == x
  return x
  
def merge(x, y, U, r):
  x = find(x, U, r)
  y = find(y, U, r)
  
  if x == y:
    return False
  #print(x,y, U)
  if r[x] < r[y]:
    x, y = y, x
  U[y] = x
  r[x] = max(r[y]+1, r[x])
  #print(x,y, U)
  return True
  
U = [i for i in range(N)]
r = [0 for _ in range(N)]

B = []
C = []
for i in range(N):
  u, v = list(map(int, input().split()))
  B.append((u, v, i))
  C.append((v, u, i))
B.sort()
C.sort()


#辺の作成
R = []
for i in range(1,N):
  c = B[i][0] - B[i-1][0]
  p1 = B[i][2]
  p2 = B[i-1][2]
  R.append((c, p1, p2))
  R.append((c, p2, p1))
  
  c = C[i][0] - C[i-1][0]
  p1 = C[i][2]
  p2 = C[i-1][2]
  R.append((c, p1, p2))
  R.append((c, p2, p1))
R.sort()

#Union Find:
U = [i for i in range(N)]
r = [0 for _ in range(N)]
#print(U)  
ans = 0
for road in R:
  c = road[0]
  x = road[1]
  y = road[2]
  if merge(x, y, U, r):
    #print(U)  
    ans += c
#print(U)    
print(ans)
# Original solution
N = int(eval(input()))

def find(x, U, r):
  p = []
  while not x == U[x]:
    p.append(x)
    x = U[x]
  for x_ in p:
    U[x_] == x
  return x
  
def merge(x, y, U, r):
  x = find(x, U, r)
  y = find(y, U, r)
  
  if x == y:
    return False
  #print(x,y, U)
  if r[x] < r[y]:
    x, y = y, x
  U[y] = x
  r[x] = max(r[y]+1, r[x])
  #print(x,y, U)
  return True
  
U = [i for i in range(N)]
r = [0 for _ in range(N)]

B = []
C = []
for i in range(N):
  u, v = list(map(int, input().split()))
  B.append((u, v, i))
  C.append((v, u, i))
B.sort()
C.sort()


#辺の作成
R = []
for i in range(1,N):
  c = B[i][0] - B[i-1][0]
  p1 = B[i][2]
  p2 = B[i-1][2]
  R.append((c, p1, p2))
  R.append((c, p2, p1))
  
  c = C[i][0] - C[i-1][0]
  p1 = C[i][2]
  p2 = C[i-1][2]
  R.append((c, p1, p2))
  R.append((c, p2, p1))
R.sort()

#Union Find:
U = [i for i in range(N)]
r = [0 for _ in range(N)]
#print(U)  
ans = 0
for road in R:
  c = road[0]
  x = road[1]
  y = road[2]
  if merge(x, y, U, r):
    #print(U)  
    ans += c
#print(U)    
print(ans)

# Optimized solution
N = int(eval(input()))

def find(x, U, r):
  p = []
  while not x == U[x]:
    p.append(x)
    x = U[x]
  for x_ in p:
    U[x_] == x
  return x
  
def merge(x, y, U, r):
  x = find(x, U, r)
  y = find(y, U, r)
  
  if x == y:
    return False
  #print(x,y, U)
  if r[x] < r[y]:
    x, y = y, x
  U[y] = x
  r[x] = max(r[y]+1, r[x])
  #print(x,y, U)
  return True
  
U = [i for i in range(N)]
r = [0 for _ in range(N)]

B = []
C = []
for i in range(N):
  u, v = list(map(int, input().split()))
  B.append((u, v, i))
  C.append((v, u, i))
B.sort()
C.sort()

#辺の作成
R = []
for i in range(1,N):
  c = B[i][0] - B[i-1][0]
  p1 = B[i][2]
  p2 = B[i-1][2]
  R.append((c, p1, p2))
  
  c = C[i][0] - C[i-1][0]
  p1 = C[i][2]
  p2 = C[i-1][2]
  R.append((c, p1, p2))
R.sort()

#Union Find:
U = [i for i in range(N)]
r = [0 for _ in range(N)]
#print(U)  
ans = 0
for road in R:
  c = road[0]
  x = road[1]
  y = road[2]
  if merge(x, y, U, r):
    #print(U)  
    ans += c
#print(U)    
print(ans)
# Original solution
from operator import itemgetter
import array

class UnionFind():
    def __init__(self,n):
        self.parent = [-1 for _ in range(n)]

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

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

    def unite(self,x,y):
        x = self.find(x)
        y = self.find(y)
        if(x == y):
            return False
        if(self.size(x)<self.size(y)):
            self.parent[y]+=self.parent[x]
            self.parent[x]=y
        else:
            self.parent[x]+=self.parent[y]
            self.parent[y]=x
        return True

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

def compute_mst_kruskal(max_v, edges):
    edges.sort(key=lambda edge: edge[2])
    uf = UnionFind(max_v)
    weight = 0

    for edge in edges:
        if not uf.same(edge[0], edge[1]):
            uf.unite(edge[0], edge[1])
            weight+=edge[2]
    return weight

def main():
    N = int(eval(input()))
    xli = []
    yli = []
    x_app = xli.append
    y_app = yli.append


    for i in range(N):
        x,y = (int(x) for x in input().split())
        x_app([x-1,i])
        y_app([y-1,i])
    xli.sort()
    yli.sort()

    edges = []
    edges_app = edges.append
    for i in range(N-1):
        edges_app((xli[i][1],xli[i+1][1],xli[i+1][0]-xli[i][0]))
        edges_app((yli[i][1],yli[i+1][1],yli[i+1][0]-yli[i][0]))
    print((compute_mst_kruskal(N,edges)))

if __name__ == '__main__':
    main()


# Optimized solution
import array
import sys
input = sys.stdin.readline

class UnionFind():
    def __init__(self,n):
        self.parent = [-1 for _ in range(n)]

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

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

    def unite(self,x,y):
        x = self.find(x)
        y = self.find(y)
        if(x == y):
            return False
        if(self.size(x)<self.size(y)):
            self.parent[y]+=self.parent[x]
            self.parent[x]=y
        else:
            self.parent[x]+=self.parent[y]
            self.parent[y]=x
        return True

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

def main():
    N = int(eval(input()))
    xli = []
    yli = []
    x_app = xli.append
    y_app = yli.append


    for i in range(N):
        x,y = (int(x) for x in input().split())
        x_app([x-1,i])
        y_app([y-1,i])
    xli.sort()
    yli.sort()

    edges = []
    edges_app = edges.append
    for i in range(N-1):
        edges_app((xli[i][1],xli[i+1][1],xli[i+1][0]-xli[i][0]))
        edges_app((yli[i][1],yli[i+1][1],yli[i+1][0]-yli[i][0]))


    edges.sort(key=lambda edge: edge[2])
    uf = UnionFind(N)
    weight = 0

    for edge in edges:
        if not uf.same(edge[0], edge[1]):
            uf.unite(edge[0], edge[1])
            weight+=edge[2]
    print(weight)

if __name__ == '__main__':
    main()
# Original solution
def find(x):
    if(par[x]==x):
        return x
    else:
        par[x]=find(par[x])
        return par[x]
def union(a,b):
    a=find(a)
    b=find(b)
    if(a==b):
        return 0
    else:
        if rank[a]>rank[b]:
            par[b]=a
        else:
            par[a]=b
            if rank[a]==rank[b]:
                rank[b]+=1
def same(a,b):
    return find(a)==find(b)
def Kruskal(Edge,E):
    cost=0
    Edge.sort(key=lambda x:x[2])
    for i in range(E):
        f,t,c=Edge[i]
        if(not same(f,t)):
            union(f,t)
            cost+=c
    return cost

N=int(eval(input()))
par=[i for i in range(N)]
rank=[0 for _ in range(N)]
p=[tuple(map(int,input().split())) for i in range(N)]
dic={p[i]:i for i in range(N)}
xp=sorted(p,key=lambda x:x[0])
yp=sorted(p,key=lambda x:x[1])
Edge=[]
for i in range(N):
    if(i>0):
        Edge.append((dic[xp[i]],dic[xp[i-1]],abs(xp[i][0]-xp[i-1][0])))
    if(i<N-1):
        Edge.append((dic[xp[i]],dic[xp[i+1]],abs(xp[i][0]-xp[i+1][0])))
for i in range(N):
    if(i>0):
        Edge.append((dic[yp[i]],dic[yp[i-1]],abs(yp[i][1]-yp[i-1][1])))
    if(i<N-1):
        Edge.append((dic[yp[i]],dic[yp[i+1]],abs(yp[i][1]-yp[i+1][1])))
Edge.sort(key=lambda x:x[2])

print((Kruskal(Edge,len(Edge))))

# Optimized solution
import sys
read=sys.stdin.readline
def find(x):
    if(par[x]==x):
        return x
    else:
        par[x]=find(par[x])
        return par[x]
def union(a,b):
    a=find(a)
    b=find(b)
    if(a==b):
        return 0
    else:
        if rank[a]>rank[b]:
            par[b]=a
        else:
            par[a]=b
            if rank[a]==rank[b]:
                rank[b]+=1
def same(a,b):
    return find(a)==find(b)
def Kruskal(Edge,E):
    cost=0
    Edge.sort(key=lambda x:x[2])
    for i in range(E):
        f,t,c=Edge[i]
        if(not same(f,t)):
            union(f,t)
            cost+=c
    return cost

N=int(eval(input()))
par=[];p=[];dic={};rank=[]
for i in range(N):
    par.append(i)
    rank.append(0)
    p.append(tuple(map(int,read().split())))
    dic[p[i]]=i
xp=sorted(p,key=lambda x:x[0])
yp=sorted(p,key=lambda x:x[1])
Edge=[]
for i in range(N):
    if(i>0):
        Edge.append((dic[xp[i]],dic[xp[i-1]],abs(xp[i][0]-xp[i-1][0])))
    if(i<N-1):
        Edge.append((dic[xp[i]],dic[xp[i+1]],abs(xp[i][0]-xp[i+1][0])))
    if(i>0):
        Edge.append((dic[yp[i]],dic[yp[i-1]],abs(yp[i][1]-yp[i-1][1])))
    if(i<N-1):
        Edge.append((dic[yp[i]],dic[yp[i+1]],abs(yp[i][1]-yp[i+1][1])))
print((Kruskal(Edge,len(Edge))))
# Original solution
class UnionFind():
    def __init__(self,n):
        self.n=n
        self.parents = [i for i in range(n+1)]
        self.size = [1]*(n+1)
    def find(self,x):
        if self.parents[x]==x:
            return x
        else:
            self.parents[x]=self.find(self.parents[x])
            return self.parents[x]
    def unite(self,x,y):
        xRoot = self.find(x)
        yRoot = self.find(y)
        if xRoot == yRoot:
            return
        if self.size[xRoot]>self.size[yRoot]:
            self.parents[yRoot] = xRoot
        else:
            self.parents[xRoot] = yRoot
            if self.size[xRoot] == self.size[yRoot]:
                self.size[yRoot]+=1

N = int(eval(input()))
nodesX = []
nodesY = []
for i in range(1,N+1):
    x,y = list(map(int,input().split()))
    nodesX.append((x,i))
    nodesY.append((y,i))
nodesX.sort()
nodesY.sort()
edges = []
for i in range(1,N):
    edges.append((nodesX[i][0]-nodesX[i-1][0],nodesX[i][1],nodesX[i-1][1]))
    edges.append((nodesY[i][0]-nodesY[i-1][0],nodesY[i][1],nodesY[i-1][1]))
edges.sort()
tree = UnionFind(N)
cost = 0
for w,s,t in edges:
    if tree.find(s)!= tree.find(t):
        tree.unite(s,t)
        cost += w
print(cost)



# Optimized solution
def main():
    import sys
    sys.setrecursionlimit(2000000)
    input = sys.stdin.readline

    class UnionFind():
        def __init__(self,n):
            self.n=n
            self.parents = [i for i in range(n+1)]
            self.size = [1]*(n+1)
        def find(self,x):
            if self.parents[x]==x:
                return x
            else:
                self.parents[x]=self.find(self.parents[x])
                return self.parents[x]
        def unite(self,x,y):
            xRoot = self.find(x)
            yRoot = self.find(y)
            if xRoot == yRoot:
                return
            if self.size[xRoot]>self.size[yRoot]:
                self.parents[yRoot] = xRoot
            else:
                self.parents[xRoot] = yRoot
                if self.size[xRoot] == self.size[yRoot]:
                    self.size[yRoot]+=1

    N = int(eval(input()))
    nodesX = []
    nodesY = []
    for i in range(1,N+1):
        x,y = list(map(int,input().split()))
        nodesX.append((x,i))
        nodesY.append((y,i))
    nodesX.sort()
    nodesY.sort()
    edges = []
    for i in range(1,N):
        edges.append((nodesX[i][0]-nodesX[i-1][0],nodesX[i][1],nodesX[i-1][1]))
        edges.append((nodesY[i][0]-nodesY[i-1][0],nodesY[i][1],nodesY[i-1][1]))
    edges.sort()
    tree = UnionFind(N)
    cost = 0
    for w,s,t in edges:
        if tree.find(s)!= tree.find(t):
            tree.unite(s,t)
            cost += w
    print(cost)

main()
# Original solution
class UnionFind():
    def __init__(self,n):
        self.n=n
        self.parents = [i for i in range(n+1)]
        self.size = [1]*(n+1)
    def find(self,x):
        if self.parents[x]==x:
            return x
        else:
            self.parents[x]=self.find(self.parents[x])
            return self.parents[x]
    def unite(self,x,y):
        xRoot = self.find(x)
        yRoot = self.find(y)
        if xRoot == yRoot:
            return
        if self.size[xRoot]>self.size[yRoot]:
            self.parents[yRoot] = xRoot
        else:
            self.parents[xRoot] = yRoot
            if self.size[xRoot] == self.size[yRoot]:
                self.size[yRoot]+=1
N = int(eval(input()))
tree = UnionFind(N)
nodes = []
for i in range(1,N+1):
    x,y = list(map(int,input().split()))
    nodes.append((i,x,y))
edges = []
nodes.sort(key=lambda x: x[1])
for i in range(1,N):
    edges.append((nodes[i][1]-nodes[i-1][1],nodes[i][0],nodes[i-1][0]))
nodes.sort(key=lambda x: x[2])
for i in range(1,N):
    edges.append((nodes[i][2]-nodes[i-1][2],nodes[i][0],nodes[i-1][0]))
edges.sort()
cost = 0
for w,s,t in edges:
    if tree.find(s)!=tree.find(t):
        tree.unite(s,t)
        cost += w
print(cost)

# Optimized solution
class UnionFind():
    def __init__(self,n):
        self.n=n
        self.parents = [i for i in range(n+1)]
        self.size = [1]*(n+1)
    def find(self,x):
        if self.parents[x]==x:
            return x
        else:
            self.parents[x]=self.find(self.parents[x])
            return self.parents[x]
    def unite(self,x,y):
        xRoot = self.find(x)
        yRoot = self.find(y)
        if xRoot == yRoot:
            return
        if self.size[xRoot]>self.size[yRoot]:
            self.parents[yRoot] = xRoot
        else:
            self.parents[xRoot] = yRoot
            if self.size[xRoot] == self.size[yRoot]:
                self.size[yRoot]+=1

N = int(eval(input()))
edges = []
nodes = []
for i in range(N):
    x,y = list(map(int,input().split()))
    nodes.append((i,x,y))
nodes.sort(key=lambda x: x[1])
for i in range(1,N):
    w = nodes[i][1]-nodes[i-1][1]
    edges.append((w,nodes[i][0],nodes[i-1][0]))
nodes.sort(key=lambda x: x[2])
for i in range(1,N):
    w = nodes[i][2] - nodes[i-1][2]
    edges.append((w,nodes[i][0],nodes[i-1][0]))
edges.sort()
tree = UnionFind(N)
cost = 0
for w,a,b in edges:
    if tree.find(a) != tree.find(b):
        tree.unite(a,b)
        cost += w
print(cost)
# Original solution
class UnionFind():
    def __init__(self,n):
        self.n=n
        self.parents = [i for i in range(n+1)]
        self.size = [1]*(n+1)
    def find(self,x):
        if self.parents[x]==x:
            return x
        else:
            self.parents[x]=self.find(self.parents[x])
            return self.parents[x]
    def unite(self,x,y):
        xRoot = self.find(x)
        yRoot = self.find(y)
        if xRoot == yRoot:
            return
        if self.size[xRoot]>self.size[yRoot]:
            self.parents[yRoot] = xRoot
        else:
            self.parents[xRoot] = yRoot
            if self.size[xRoot] == self.size[yRoot]:
                self.size[yRoot]+=1

N = int(eval(input()))
edges = []
nodes = []
for i in range(N):
    x,y = list(map(int,input().split()))
    nodes.append((i,x,y))
nodes.sort(key=lambda x: x[1])
for i in range(1,N):
    w = nodes[i][1]-nodes[i-1][1]
    edges.append((w,nodes[i][0],nodes[i-1][0]))
nodes.sort(key=lambda x: x[2])
for i in range(1,N):
    w = nodes[i][2] - nodes[i-1][2]
    edges.append((w,nodes[i][0],nodes[i-1][0]))
edges.sort()
tree = UnionFind(N)
cost = 0
for w,a,b in edges:
    if tree.find(a) != tree.find(b):
        tree.unite(a,b)
        cost += w
print(cost)

# Optimized solution
class UnionFind():
    def __init__(self,n):
        self.n=n
        self.parents = [i for i in range(n+1)]
        self.size = [1]*(n+1)
    def find(self,x):
        if self.parents[x]==x:
            return x
        else:
            self.parents[x]=self.find(self.parents[x])
            return self.parents[x]
    def unite(self,x,y):
        xRoot = self.find(x)
        yRoot = self.find(y)
        if xRoot == yRoot:
            return
        if self.size[xRoot]>self.size[yRoot]:
            self.parents[yRoot] = xRoot
            self.size[xRoot] += self.size[yRoot]
            self.size[yRoot] = 0
        else:
            self.parents[xRoot] = yRoot
            self.size[yRoot] += self.size[xRoot]
            self.size[xRoot] = 0

N = int(eval(input()))
XY = [[i]+list(map(int,input().split())) for i in range(N)]
edges = []
XY.sort(key=lambda x: x[1])
for j in range(1,N):
    edges.append((XY[j-1][0],XY[j][0],XY[j][1]-XY[j-1][1]))
XY.sort(key=lambda x: x[2])
for j in range(1,N):
    edges.append((XY[j-1][0],XY[j][0],XY[j][2]-XY[j-1][2]))

cost = 0
edges.sort(key=lambda x: x[2])
tree = UnionFind(N)
for i,j,c in edges:
    if tree.find(i)!=tree.find(j):
        tree.unite(i,j)
        cost += c

print(cost)
# Original solution
import heapq
import sys
input = sys.stdin.readline
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)

    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 union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        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 same_check(self, x, y):
        return self.find(x) == self.find(y)

def solve():
  n = int(eval(input()))
  query = []
  xquery = []
  yquery = []
  for i in range(n):
    x,y = (int(i) for i in input().split())
    xquery.append((x,y,i))
    yquery.append((y,x,i))
  xquery = sorted(xquery)
  yquery = sorted(yquery)
  for i in range(n-1):
    tx,ty,place = xquery[i]
    tx2,ty2,place2 = xquery[i+1]
    cost = min(abs(tx2-tx),abs(ty2-ty))
    heapq.heappush(query,(cost,place,place2))
    
    ty,tx,place = yquery[i]
    ty2,tx2,place2 = yquery[i+1]
    cost = min(abs(tx2-tx),abs(ty2-ty))
    heapq.heappush(query,(cost,place,place2))
  ct = 0
  uf = UnionFind(n)
  while len(query) > 0:
    cost,place1,place2 = heapq.heappop(query)
    if uf.same_check(place1,place2):
      continue
    else:
      uf.union(int(place1),int(place2))
      ct += cost
  print(ct)
      

solve()

# Optimized solution
#https://atcoder.jp/contests/abc065/submissions/5881131
import sys
input = sys.stdin.readline
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)

    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 union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        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 same_check(self, x, y):
        return self.find(x) == self.find(y)

def MST(n, E):
    E = sorted(E, key=lambda x: x[2])
    uf = UnionFind(n)
    ct = 0
    for i,j,cost in E:
      if uf.same_check(i,j):
        continue
      else:
        uf.union(i,j)
        ct += cost
    return ct
  
def solve():
  N = int(eval(input()))
  X = []
  append=X.append
  for i in range(N):
    x, y = list(map(int, input().split()))
    append((i, x, y))
 
  F = []
  append = F.append
  Y = sorted(X, key = lambda x: x[1])
  for i in range(len(Y)-1):
    append((Y[i][0], Y[i+1][0], abs(Y[i+1][1]-Y[i][1])))
 
  Y = sorted(X, key = lambda x: x[2])
  for i in range(len(Y)-1):
    append((Y[i][0], Y[i+1][0], abs(Y[i+1][2]-Y[i][2])))
 
  print((MST(N, F)))

solve()
# Original solution
class UnionFind():
    def __init__(self,n):
        self.n=n
        self.par=[i for i in range(n)]
        self.size=[1]*n
    def find(self,x):
        if x==self.par[x]:
            return self.par[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:
            return
        if self.size[x]>self.size[y]:
            self.size[x]+=self.size[y]
            self.par[y]=x
        else:
            self.size[y]+=self.size[x]
            self.par[x]=y

n=int(eval(input()))

x_list=[]
y_list=[]

for i in range(n):
    x,y=list(map(int,input().split()))
    x_list.append((x,i))
    y_list.append((y,i))
x_list.sort()
y_list.sort()
edges=[]

for i in range(1,n):
    edges.append((x_list[i][0]-x_list[i-1][0],x_list[i][1],x_list[i-1][1]))

    edges.append((y_list[i][0]-y_list[i-1][0],y_list[i][1],y_list[i-1][1]))

edges.sort()
uf=UnionFind(n)
ans=0
for e in edges:
    wt=e[0]
    x=e[1]
    y=e[2]
    if uf.find(x)==uf.find(y):
        continue
    ans+=wt
    uf.unite(x,y)
print(ans)



# Optimized solution
class UnionFind():
    def __init__(self,n):
        self.n=n
        self.par=[i for i in range(n)]
        self.size=[1]*n
    def find(self,x):
        if x==self.par[x]:
            return self.par[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:
            return
        if self.size[x]>self.size[y]:
            self.size[x]+=self.size[y]
            self.par[y]=x
        else:
            self.size[y]+=self.size[x]
            self.par[x]=y

import sys
input=sys.stdin.buffer.readline
n=int(eval(input()))

x_list=[]
y_list=[]

for i in range(n):
    x,y=list(map(int,input().split()))
    x_list.append((x,i))
    y_list.append((y,i))
x_list.sort()
y_list.sort()
edges=[]

for i in range(1,n):
    edges.append((x_list[i][0]-x_list[i-1][0],x_list[i][1],x_list[i-1][1]))

    edges.append((y_list[i][0]-y_list[i-1][0],y_list[i][1],y_list[i-1][1]))

edges.sort()
uf=UnionFind(n)
ans=0
for e in edges:
    wt=e[0]
    x=e[1]
    y=e[2]
    if uf.find(x)==uf.find(y):
        continue
    ans+=wt
    uf.unite(x,y)
print(ans)