CodeEff/ECCO huggingface dataset:
# Original solution
import heapq
def cost(a, b, c, d):
    return min(abs(a-c), abs(b-d))

N = int(eval(input()))
T = []
for i in range(N):
    x, y = list(map(int, input().split()))
    if (x, y) not in T:
        T.append((x, y))
lenT = len(T)
Tx, Ty = sorted(T, key = lambda t:t[0]), sorted(T, key = lambda t:t[1])
P = [[] for i in range(lenT)]
for i in range(lenT-1):
    xc, yc = cost(Tx[i][0], Tx[i][1], Tx[i+1][0], Tx[i+1][1]), cost(Ty[i][0], Ty[i][1], Ty[i+1][0], Ty[i+1][1])
    P[T.index(Tx[i])].append([xc, T.index(Tx[i+1])])
    P[T.index(Tx[i+1])].append([xc, T.index(Tx[i])])
    P[T.index(Ty[i])].append([yc, T.index(Ty[i+1])])
    P[T.index(Ty[i+1])].append([yc, T.index(Ty[i])])

Visit = [False for i in range(lenT)]
Visit[0] = True
Q = [p for p in P[0]]
heapq.heapify(Q)
Total = 0
while Q:
    nextCost, nextNode = heapq.heappop(Q)
    if Visit[nextNode] == False:
        Total += nextCost
        Visit[nextNode] = True
        for t in P[nextNode]:
            if Visit[t[1]] == False:
                heapq.heappush(Q, [t[0], t[1]])
print(Total)

# Optimized solution
import sys
from operator import itemgetter
import heapq

def solve():
    input = sys.stdin.readline
    N = int(eval(input()))
    town = dict()
    road = [None] * N
    roadx, roady = [None] * N, [None] * N
    for i in range(N):
        x, y = list(map(int, input().split()))
        town[(x, y, i)] = i
        road[i] = (x, y, i)
        roadx[i] = (x, y, i)
        roady[i] = (x, y, i)
    roadx.sort()
    roadx_id = dict()
    roady.sort(key = itemgetter(1))
    roady_id = dict()
    for i in range(N):
        roadx_id[roadx[i]] = i
        roady_id[roady[i]] = i

    visited = [False] * N
    q = []
    heapq.heapify(q)
    heapq.heappush(q, (0, 0)) #(cost, town_id)
    cost = 0
    while q:
        add_cost, id = heapq.heappop(q)
        #print(add_cost, id, cost)
        #print(visited)
        if not visited[id]:
            cost += add_cost
            visited[id] = True
            for s in range(2):
                nx = roadx_id[road[id]] + (-1) ** s #roadxにおけるid
                if 0 <= nx < N:
                    if not visited[town[roadx[nx]]]: heapq.heappush(q, (min(abs(road[id][0] - roadx[nx][0]), abs(road[id][1] - roadx[nx][1])), town[roadx[nx]]))
                
                ny = roady_id[road[id]] + (-1) ** s #roadyにおけるid
                if 0 <= ny < N:
                    if not visited[town[roady[ny]]]: heapq.heappush(q, (min(abs(road[id][1] - roady[ny][1]), abs(road[id][1] - roady[ny][1])), town[roady[ny]]))
    
    print(cost)

    return 0

if __name__ == "__main__":
    solve()
# Original solution
from heapq import *
N = int(eval(input()))
X,Y=[],[]
for n in range(N):
  x,y=list(map(int,input().split()))
  X.append((x, n))
  Y.append((y, n))
X.sort()
Y.sort()
D=[[] for v in range(N)]
for n in range(N-1):
  cost = X[n+1][0]-X[n][0]
  D[X[n+1][1]].append((cost,X[n][1]))
  D[X[n][1]].append((cost,X[n+1][1]))
  cost=Y[n+1][0]-Y[n][0]
  D[Y[n+1][1]].append((cost,Y[n][1]))
  D[Y[n][1]].append((cost,Y[n+1][1]))

visited=[0]*N
pq = []
for w, t in D[0]:
  heappush(pq,(w,t))
visited[0]=1

ans = 0
while pq:
  w,t=heappop(pq)
  if visited[t]:
    continue
  visited[t]=1
  ans+=w
  for w,s in D[t]:
    if visited[s]==0:
      heappush(pq,(w,s))
print (ans)

# Optimized solution
N = int(eval(input()))
XYI = [tuple(map(int,input().split() + [i])) for i in range(N)]
sx = sorted(XYI, key=lambda x:x[0])
sy = sorted(XYI, key=lambda x:x[1])

es = []
for (x0,_,i0),(x1,_,i1) in zip(sx,sx[1:]):
  es.append((x1-x0, i0, i1))
for (_,y0,i0),(_,y1,i1) in zip(sy,sy[1:]):
  es.append((y1-y0, i0, i1))
es.sort(key=lambda x:x[0])
 
class UnionFind:
  def __init__(self,N):
    self.parent = [i for i in range(N)]
    self._size = [1] * N
    self.count = 0
  def root(self,a):
    if self.parent[a] == a:
      return a
    else:
      self.parent[a] = self.root(self.parent[a])
      return self.parent[a]
  def is_same(self,a,b):
    return self.root(a) == self.root(b)
  def unite(self,a,b):
    ra = self.root(a)
    rb = self.root(b)
    if ra == rb: return
    if self._size[ra] < self._size[rb]: ra,rb = rb,ra
    self._size[ra] += self._size[rb]
    self.parent[rb] = ra
    self.count += 1
  def size(self,a):
    return self._size[self.root(a)]

uf = UnionFind(N)
ans = 0
for d,a,b in es:
  if uf.is_same(a,b): continue
  uf.unite(a,b)
  ans += d
print(ans)
# Original solution
n=int(eval(input()))
a=sorted([[i]+list(map(int,input().split()))for i in range(n)],key=lambda x:x[1])
s=[]
for i in range(n-1):
    s.append((a[i+1][1]-a[i][1],a[i][0],a[i+1][0]))
a=sorted(a,key=lambda x:x[2])
for i in range(n-1):
    s.append((a[i+1][2]-a[i][2],a[i][0],a[i+1][0]))
s.sort()
t=[i for i in range(n)]
def f(x):
    if x==t[x]:
        return x
    x=t[x]
    return f(t[x])
c=0
for i,j,h in s:
    j,h=f(j),f(h)
    if h!=j:
        t[j]=h
        c+=i
print(c)

# Optimized solution
n=int(eval(input()))
a=sorted([[i]+list(map(int,input().split()))for i in range(n)],key=lambda x:x[1])
s=[]
for i in range(n-1):
    s.append((a[i+1][1]-a[i][1],a[i][0],a[i+1][0]))
a=sorted(a,key=lambda x:x[2])
for i in range(n-1):
    s.append((a[i+1][2]-a[i][2],a[i][0],a[i+1][0]))
s.sort()
t=[i for i in range(n)]
def f(x):
    if x==t[x]:
        return x
    t[x]=f(t[x])
    return f(t[x])
c=0
for i,j,h in s:
    j,h=f(j),f(h)
    if h!=j:
        t[j]=h
        c+=i
print(c)
# Original solution
import sys
from  heapq import heappush, heappop, heapify

N=int(eval(input()))

par=[ i for i in range(N) ]

def root(x):
	if par[x]==x:
		return x
	else:
		par[x]=root( par[x] )
		return par[x]

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

def unite(x,y):
	x=root(x)
	y=root(y)
	if x==y: return
	par[x]=y



X=[]
Y=[]
for i in range(N):
	x,y=list(map(int, sys.stdin.readline().split())) 
	X.append( (x,i) )
	Y.append( (y,i) )

X.sort(key=lambda x: x[0])
Y.sort(key=lambda x: x[0])

hq=[]

prev_x=None
prev_i=None
for x,i in X:
	if prev_x is not None:	
		heappush( hq, ( x-prev_x, i, prev_i) )
	prev_x=x
	prev_i=i

prev_x=None
prev_i=None
for x,i in Y:
	if prev_x is not None:	
		heappush( hq, ( x-prev_x, i, prev_i) )
	prev_x=x
	prev_i=i


ans=0
while hq:
	d,a,b=heappop(hq)
	if not same(a,b):
		ans+=d
		unite(a,b)
		
print (ans)

# Optimized solution
# -*- coding: utf-8 -*-
import sys
N=int(sys.stdin.readline().strip())
V=[]    #頂点の集合 (x座標、y座標、頂点番号)
for v in range(N):   #v:頂点番号
    x,y=tuple(map(int, sys.stdin.readline().split()))
    V.append((x,y,v+1))

#頂点をy軸でソート
V.sort(key=lambda x:(x[0]) )
E=[]    #辺の集合 (辺の長さ、頂点番号、頂点番号)
for i in range(N-1):
    fro_x,fro=V[i][0],V[i][2]
    to_x,to=V[i+1][0],V[i+1][2]
    E.append( (abs(fro_x-to_x),fro,to))

#頂点をx軸でソート
V.sort(key=lambda x:(x[1]) )
for i in range(N-1):
    fro_y,fro=V[i][1],V[i][2]
    to_y,to=V[i+1][1],V[i+1][2]
    E.append( (abs(fro_y-to_y),fro,to))

#辺の集合を辺の長さで昇順ソート
E.sort(key=lambda x:(x[0]) )


par=[ i for i in range(N+1) ]
size=[ 1 for i in range(N+1) ]

#Union Find
def root(x):
    while par[x]!=x:
        x=par[x]
    return x

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

def unite(x,y):
    x=root(x)
    y=root(y)
    if x==y: return
    if size[y]<size[x]: x,y=y,x  #yの要素数を大きくする
    size[y]+=size[x]
    par[x]=y #yが親ノード

def getsize(x):
	return size[root(x)]

ans=0
for cost,v1,v2 in E:
    if same(v1,v2) is False:
        ans+=cost
        unite(v1,v2)

print(ans)
# Original solution
import heapq
import sys
input = sys.stdin.readline

def main():
    N = int(eval(input()))
    x,y = [],[]
    root = [[] for _ in range(N)]
    go = [True for _ in range(N)]
    for i in range(N):
        _x,_y = list(map(int,input().split()))
        x.append((_x,i))
        y.append((_y,i))
        
    x.sort()
    y.sort()
    
    for i in range(N-1):
        dx = x[i+1][0] - x[i][0]
        dy = y[i+1][0] - y[i][0]
        root[x[i][1]].append((dx,x[i+1][1]))
        root[x[i+1][1]].append((dx,x[i][1]))
        root[y[i][1]].append((dy,y[i+1][1]))
        root[y[i+1][1]].append((dy,y[i][1]))
    
    ans = 0    
    queue = root[0]
    heapq.heapify(queue)
    go[0] = False
    while queue:
        cost,following = heapq.heappop(queue)
        if not go[following]:
            continue
        go[following] = False
        for e in root[following]:
            if go[e[1]]:
                heapq.heappush(queue,e)
        ans += cost
        
    print(ans)
    
if __name__ == "__main__":
    main()

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

def main():
    N = int(eval(input()))
    rx,ry = [],[]
    _root = []
    for i in range(N):
        a,b = list(map(int,input().split()))
        rx.append((a,i))
        ry.append((b,i))
    
    I = [i for i in range(N)]
    rank = [1 for _ in range(N)]
    def root(x):
        if x == I[x]:
            return x
        I[x] = root(I[x])
        return I[x]
    
    def unite(x,y):
        px,py = root(x),root(y)
        rx,ry = rank[px],rank[py]
        if rx > ry:
            I[py] = px
        else:
            I[px] = py
            if rx == ry:
                rank[py] += 1

    ans = 0
    rx.sort()
    ry.sort()
    for i in range(N-1):
        dx = rx[i+1][0]-rx[i][0]
        dy = ry[i+1][0]-ry[i][0]
        _root.append((dx,rx[i][1],rx[i+1][1]))
        _root.append((dy,ry[i][1],ry[i+1][1]))
        
    _root.sort()
    a = len(_root)
    for i in range(a):
        cost,now,fol = _root[i]
        if (root(now) == root(fol)):
            continue
        ans += cost
        unite(now,fol)
        
    print(ans)
    
if __name__ == "__main__":
    main()
# Original solution
N = int(eval(input()))
ixy=[]
for i in range(N):
  x, y = list(map(int,input().split()))
  ixy+=[[i,x,y]]
costs = [[] for i in range(N)]

ixy.sort(key=lambda x:x[1])
for j in range(N-1):
  costs[ixy[j][0]] += [[ixy[j+1][0],abs(ixy[j][1]-ixy[j+1][1])]]
  costs[ixy[j+1][0]] += [[ixy[j][0],abs(ixy[j][1]-ixy[j+1][1])]]
ixy.sort(key=lambda y:y[2])
for j in range(N-1):
  costs[ixy[j][0]] += [[ixy[j+1][0],abs(ixy[j][2]-ixy[j+1][2])]]
  costs[ixy[j+1][0]] += [[ixy[j][0],abs(ixy[j][2]-ixy[j+1][2])]]

import heapq
pq = []
heapq.heappush(pq,[0,0])

visited = [0]*N
ans = 0
while pq:
  cost, v = heapq.heappop(pq)

  if visited[v]: continue
  
  ans += cost
  visited[v]=1
  
  for u,c in costs[v]:
    if not visited[u]:
      heapq.heappush(pq, [c,u])

print(ans)

# Optimized solution
class UnionFind:
  def __init__(self, size):
  # 負の値はルート (集合の代表) で集合の個数
  # 正の値は次の要素を表す
    self.table = [-1 for _ in range(size)]

  # 集合の代表を求める
  def find(self, x):
    if self.table[x] < 0:
      return x
    else:
      # 経路の圧縮
      self.table[x] = self.find(self.table[x])
      return self.table[x]

  # 併合
  def union(self, x, y):
    s1 = self.find(x)
    s2 = self.find(y)
    if s1 != s2:
      if self.table[s1] <= self.table[s2]:
        # 小さいほうが個数が多い
        self.table[s1] += self.table[s2]
        self.table[s2] = s1
      else:
        self.table[s2] += self.table[s1]
        self.table[s1] = s2
      return True
    return False

N = int(eval(input()))
ixy=[]
for i in range(N):
  x, y = list(map(int,input().split()))
  ixy+=[[i,x,y]]
costs = []

ixy.sort(key=lambda x:x[1])
for j in range(N-1):
  costs += [(ixy[j][0], ixy[j+1][0], ixy[j+1][1]-ixy[j][1])]
  costs += [(ixy[j+1][0], ixy[j][0], ixy[j+1][1]-ixy[j][1])]
ixy.sort(key=lambda y:y[2])
for j in range(N-1):
  costs += [(ixy[j][0], ixy[j+1][0], ixy[j+1][2]-ixy[j][2])]
  costs += [(ixy[j+1][0], ixy[j][0], ixy[j+1][2]-ixy[j][2])]

costs.sort(key=lambda cost:cost[2])
ans = 0
roots = UnionFind(N)
for cost in costs:
  u, v, c = cost
  if roots.find(u)!=roots.find(v):
    roots.union(u, v)
    ans += c
    
print(ans)
# Original solution
#UnionFind木とそれを利用したクラスカル法
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 same(self, x, y):
        return self.find(x) == self.find(y)

    def nums(self,x):
        return abs(self.parents[self.find(x)])

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())


N = int(eval(input()))
A = [list(map(int, input().split()))+[i] for i in range(N)]
edge = []
A.sort()
for i in range(N-1):
    w = min(abs(A[i+1][0]-A[i][0]),abs(A[i+1][1]-A[i][1]))
    edge.append((w,A[i][2],A[i+1][2]))
A.sort(key=lambda x:x[1])
for i in range(N-1):
    w = min(abs(A[i+1][0]-A[i][0]),abs(A[i+1][1]-A[i][1]))
    edge.append((w,A[i][2],A[i+1][2]))

edge.sort()

uf = UnionFind(N)
ans = 0
for i in range(len(edge)):
    u,x,y = edge[i]
    if not uf.same(x,y):
        uf.union(x,y)
        ans += u
print(ans)

# Optimized solution
#UnionFind木とそれを利用したクラスカル法
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 same(self, x, y):
        return self.find(x) == self.find(y)

    def nums(self,x):
        return abs(self.parents[self.find(x)])

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())


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

edge.sort()

uf = UnionFind(N)
ans = 0
for i in range(len(edge)):
    u,x,y = edge[i]
    if not uf.same(x,y):
        uf.union(x,y)
        ans += u
print(ans)
# Original solution
#UnionFind木とそれを利用したクラスカル法
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 same(self, x, y):
        return self.find(x) == self.find(y)

    def nums(self,x):
        return abs(self.parents[self.find(x)])

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())


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

edge.sort()

uf = UnionFind(N)
ans = 0
for i in range(len(edge)):
    u,x,y = edge[i]
    if not uf.same(x,y):
        uf.union(x,y)
        ans += u
print(ans)

# Optimized solution
#最小全域木問題、プリム法
from heapq import *
def solve():
    N = int(eval(input()))
    A = [list(map(int, input().split()))+[i] for i in range(N)]
    edge = [[] for _ in range(N)]
    A.sort()
    for i in range(N-1):
        w = A[i+1][0]-A[i][0]
        edge[A[i][2]].append((w,A[i+1][2]))
        edge[A[i+1][2]].append((w,A[i][2]))
    A.sort(key=lambda x:x[1])
    for i in range(N-1):
        w = A[i+1][1]-A[i][1]
        edge[A[i][2]].append((w,A[i+1][2]))
        edge[A[i+1][2]].append((w,A[i][2]))
    bridges = []
    heapify(bridges)
    used = [False]*N
    used[0] = True
    ans = 0
    for w,v in edge[0]:
        heappush(bridges,(w,v))
    while len(bridges)>0:
        w,v = heappop(bridges)
        if used[v]==False:
            ans += w
            used[v] = True
            for w,u in edge[v]:
                if used[u]==False:
                    heappush(bridges,(w,u))
    return ans
print((solve()))
# Original solution
import heapq
class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parent = [i for i in range(n)]
        self.rank = [0] * n
    
    def find(self, x):
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]

    def union(self, x, y):
        x, y = self.find(x), self.find(y)
        if x == y: return
        
        if self.rank[x] < self.rank[y]:
            self.parent[x] = y
        else:
            self.parent[y] = x
            self.rank[x] += (self.rank[x] == self.rank[y])

def kruskal(n, edge):
    ans = 0
    uf = UnionFind(n)
    while True:
        d, v, u = heapq.heappop(edge)
        
        if uf.find(v) != uf.find(u):
            uf.union(v, u)
            n -= 1
            ans += d
        if n < 2: return ans
    return ans

n = int(eval(input()))
x, y = [None]*n, [None]*n
dist = [[0] * n for _ in range(n)]

for i in range(n):
    a, b = list(map(int, input().split()))
    x[i] = (a, i)
    y[i] = (b, i)

x.sort(key=lambda x:x[0])
y.sort(key=lambda y:y[0])

edge = []
for i in range(n-1):
    heapq.heappush(edge, (x[i+1][0]-x[i][0], x[i][1], x[i+1][1]))
    heapq.heappush(edge, (y[i+1][0]-y[i][0], y[i][1], y[i+1][1]))

del x, y
print((kruskal(n, edge)))

# Optimized solution
import heapq
class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parent = [i for i in range(n)]
        self.rank = [0] * n
    
    def find(self, x):
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]

    def union(self, x, y):
        x, y = self.find(x), self.find(y)
        if x == y: return
        
        if self.rank[x] < self.rank[y]:
            self.parent[x] = y
        else:
            self.parent[y] = x
            self.rank[x] += (self.rank[x] == self.rank[y])

def kruskal(n, edge):
    ans = 0
    uf = UnionFind(n)
    while True:
        d, v, u = heapq.heappop(edge)
        
        if uf.find(v) != uf.find(u):
            uf.union(v, u)
            n -= 1
            ans += d
        if n < 2: return ans
    return ans

n = int(eval(input()))
x, y = [None]*n, [None]*n

for i in range(n):
    a, b = list(map(int, input().split()))
    x[i] = (a, i)
    y[i] = (b, i)

x.sort(key=lambda x:x[0])
y.sort(key=lambda y:y[0])

edge = []
for i in range(n-1):
    heapq.heappush(edge, (x[i+1][0]-x[i][0], x[i][1], x[i+1][1]))
    heapq.heappush(edge, (y[i+1][0]-y[i][0], y[i][1], y[i+1][1]))

del x, y
print((kruskal(n, edge)))
# Original solution
class UnionFind(object):
  def __init__(self,n):
    *self.par,=list(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

n=int(eval(input()))
x=[[0,0] for _ in range(n)]
y=[[0,0] for _ in range(n)]

for i in range(n):
  x[i][0],y[i][0]=list(map(int,input().split()))
  x[i][1],y[i][1]=i+1,i+1

dx,dy=[],[]
x,y=sorted(x),sorted(y)
for i in range(n-1):
  dx.extend([(abs(x[i][0]-x[i+1][0]),x[i][1],x[i+1][1])])
  dy.extend([(abs(y[i][0]-y[i+1][0]),y[i][1],y[i+1][1])])

target=sorted(dx+dy)
tree=UnionFind(n)
cnt,cost,i=0,0,0

while cnt<n-1:
  c,a,b=target[i]
  if tree.find(a)!=tree.find(b):
    cost+=c
    tree.union(a,b)
    cnt+=1
  i+=1

print(cost)


# Optimized solution
class UnionFind(object):
  def __init__(self,n):
    self.parent={i:i for i in range(1,n+1)}
    self.size={i:1 for i in range(1,n+1)}
  def find(self,a):
    if self.parent[a]!=a:
      self.parent[a]=self.find(self.parent[a])
    return self.parent[a]
  def unite(self,a,b):
    a=self.find(a)
    b=self.find(b)
    if a==b:return
    if self.size[a]>self.size[b]:
      self.size[a]+=self.size[b]
      self.parent[b]=a
    else:
      self.size[b]+=self.size[a]
      self.parent[a]=b
  def isunited(self,a,b):
    return self.find(a)==self.find(b)

N=int(eval(input()))
l=[[i+1]+list(map(int,input().split())) for i in range(N)]
o=[]

l.sort(key=lambda x:x[1])
for i in range(N-1):
    o.append((l[i][0],l[i+1][0],l[i+1][1]-l[i][1]))

l.sort(key=lambda x:x[2])
for i in range(N-1):
    o.append((l[i][0],l[i+1][0],l[i+1][2]-l[i][2]))

o.sort(key=lambda x:x[2])

ans=0
uft=UnionFind(N)
for town1,town2,cost in o:
    if not uft.isunited(town1,town2):
        uft.unite(town1,town2)
        ans+=cost

print(ans)
# Original solution
class UnionFind(object):
  def __init__(self,n):
    self.parent={i:i for i in range(1,n+1)}
    self.size={i:1 for i in range(1,n+1)}
  def find(self,a):
    if self.parent[a]!=a:
      self.parent[a]=self.find(self.parent[a])
    return self.parent[a]
  def unite(self,a,b):
    a=self.find(a)
    b=self.find(b)
    if a==b:return
    if self.size[a]>self.size[b]:
      self.size[a]+=self.size[b]
      self.parent[b]=a
    else:
      self.size[b]+=self.size[a]
      self.parent[a]=b
  def isunited(self,a,b):
    return self.find(a)==self.find(b)

N=int(eval(input()))
l=[[i+1]+list(map(int,input().split())) for i in range(N)]
o=[]

l.sort(key=lambda x:x[1])
for i in range(N-1):
    o.append((l[i][0],l[i+1][0],l[i+1][1]-l[i][1]))

l.sort(key=lambda x:x[2])
for i in range(N-1):
    o.append((l[i][0],l[i+1][0],l[i+1][2]-l[i][2]))

o.sort(key=lambda x:x[2])

ans=0
uft=UnionFind(N)
for town1,town2,cost in o:
    if not uft.isunited(town1,town2):
        uft.unite(town1,town2)
        ans+=cost

print(ans)

# Optimized solution
class UnionFind(object):
    def __init__(self, n):
        self.parent={i:i for i in range(1,n+1)}
        self.size={i:1 for i in range(1,n+1)}
    def find(self, a):
        if self.parent[a]!=a:
            self.parent[a]=self.find(self.parent[a])
        return self.parent[a]
    def getsize(self, a):
        return self.size[self.find(a)]
    def unite(self, a, b):
        a=self.find(a)
        b=self.find(b)
        if a==b:return
        if self.size[a]>self.size[b]:
            self.size[a]+=self.size[b]
            self.parent[b]=a
        else:
            self.size[b]+=self.size[a]
            self.parent[a]=b
    def isunited(self, a, b):
        return self.find(a)==self.find(b)


N = int(eval(input()))
l = []
q = []
for i in range(N):
    x, y = list(map(int, input().split()))
    l.append((x, y, i+1))

l.sort()
for i in range(N-1):
    x1, y1, s = l[i]
    x2, y2, t = l[i+1]
    q.append((abs(x1-x2), s, t))

l.sort(key=lambda x:x[1])
for i in range(N-1):
    x1, y1, s = l[i]
    x2, y2, t = l[i+1]
    q.append((abs(y1-y2), s, t))

uft = UnionFind(N)
ans = 0
q.sort()

for cost, s, t in q:
    if not uft.isunited(s, t):
        ans += cost
        uft.unite(s, t)

print(ans)