CodeEff/ECCO huggingface dataset:
# Original solution
import queue,sys,copy
sys.setrecursionlimit(10**7)
INF = 10**10
N = int(eval(input()))
x = [0 for _ in range(N)]
y = [0 for _ in range(N)]
for i in range(N):
    x[i], y[i] = list(map(int,input().split()))
ix = [i for i in range(N)]
sort_x_ix = sorted(ix, key=lambda i:x[i])
sort_x = [x[i] for i in sort_x_ix]
sort_y_ix = sorted(ix, key=lambda i:y[i])
sort_y = [y[i] for i in sort_y_ix]

g = [i for i in range(N+1)]
def root(x):
    if g[x] == x : return x
    g[x] = root(g[x])
    return g[x]
q = []
for i in range(N-1):
    q.append((sort_x[i+1]-sort_x[i],sort_x_ix[i],sort_x_ix[i+1]))
    q.append((sort_y[i+1]-sort_y[i],sort_y_ix[i],sort_y_ix[i+1]))

q.sort()
ans = 0
cnt = N

for d,s,t in q:
    if cnt <= 1: break
    if root(s) != root(t):
        ans += d
        cnt -= 1
        g[root(t)] = g[s]
print(ans)

# Optimized solution
import sys,queue,math,copy,itertools,bisect,collections,heapq

def main():
    LI = lambda : [int(x) for x in sys.stdin.readline().split()]
    NI = lambda : int(sys.stdin.readline())

    N = NI()
    xy = [LI() for _ in range(N)]

    x = [(xy[i][0],i) for i in range(N)]
    y = [(xy[i][1],i) for i in range(N)]

    x.sort()
    y.sort()

    edge = []
    p,i = x[0]
    for q,j in x[1:]:
        edge.append((q-p,i,j))
        p,i = q,j

    p,i = y[0]
    for q,j in y[1:]:
        edge.append((q-p,i,j))
        p,i = q,j

    edge.sort()

    g = [i for i in range(N + 1)]
    g_num = [1 for i in range(N + 1)]

    def find(x):
        if g[x] == x: return x
        g[x] = find(g[x])
        return g[x]

    def union(x, y):
        if find(x) == find(y): return
        if g_num[g[x]] < g_num[g[y]]: x, y = y, x
        g_num[g[x]] += g_num[g[y]]
        g_num[g[y]] = 0
        g[g[y]] = g[x]

    ans = 0
    for v,i,j in edge:
        if find(i) != find(j):
            ans += v
            union(i,j)

    print(ans)



if __name__ == '__main__':
    main()
# Original solution
from heapq import *
from collections import defaultdict
INF = float('inf')
class Prim:

    def __init__(self,N):#Nはグラフのノード数
        self.N = N
        self.cost = defaultdict(list)
        self.used = [False for _ in range(N)]
    
    def setcost(self,u,v,w):
        self.cost[u].append((v,w))
        self.cost[v].append((u,w))
    
    def prim(self):
        que = []
        heapify(que)
        used = self.used
        for e in self.cost[0]:
            heappush(que,[e[1],e[0]])
        used[0] = True
        res = 0
        while que:
            p = heappop(que)
            cos,v = p
            if used[v]:continue
            self.used[v] = True
            for e in self.cost[v]:
                if not used[e[0]]:
                    heappush(que,[e[1],e[0]])      
            res += cos
        return res

def main():
    N = int(eval(input()))
    cost = []
    for i in range(N):
        x,y = list(map(int,input().split()))
        cost.append((x,y,i))
    prim = Prim(N)
    x = sorted(cost,key=lambda x: x[0])
    y = sorted(cost,key=lambda x: x[1])
    for i in range(N-1):
        a,b,u = x[i]
        c,d,v = x[i+1]
        w = min(abs(a-c),abs(b-d))
        prim.setcost(u,v,w)
        e,f,s = y[i]
        g,h,t = y[i+1]
        u = min(abs(e-g),abs(f-h))
        prim.setcost(s,t,u)
    ans = prim.prim()
    print(ans)
if __name__ == "__main__":
    main()

# Optimized solution
from heapq import *
from collections import defaultdict
INF = float('inf')
class Prim:

    def __init__(self,N):#Nはグラフのノード数
        self.N = N
        self.cost = defaultdict(list)
        self.used = [False for _ in range(N)]
    
    def setcost(self,u,v,w):
        self.cost[u].append((v,w))
        self.cost[v].append((u,w))
    
    def prim(self):
        que = []
        heapify(que)
        used = self.used
        for e in self.cost[0]:
            heappush(que,[e[1],e[0]])
        used[0] = True
        res = 0
        while que:
            p = heappop(que)
            cos,v = p
            if used[v]:continue
            self.used[v] = True
            for e in self.cost[v]:
                if not used[e[0]]:
                    heappush(que,[e[1],e[0]])      
            res += cos
        return res

def main():
    N = int(eval(input()))
    cost = []
    for i in range(N):
        x,y = list(map(int,input().split()))
        cost.append((x,y,i))
    prim = Prim(N)
    x = tuple(sorted(cost,key=lambda x: x[0]))
    y = tuple(sorted(cost,key=lambda x: x[1]))
    for i in range(N-1):
        a,b,u = x[i]
        c,d,v = x[i+1]
        w = min(abs(a-c),abs(b-d))
        prim.setcost(u,v,w)
        e,f,s = y[i]
        g,h,t = y[i+1]
        u = min(abs(e-g),abs(f-h))
        prim.setcost(s,t,u)
    ans = prim.prim()
    print(ans)
if __name__ == "__main__":
    main()
# Original solution
# -*- coding: utf-8 -*-
import sys
from heapq import heappush,heappop,heapify
sys.setrecursionlimit(10**9)
INF=10**18
MOD=10**9+7
input=lambda: sys.stdin.readline().rstrip()
YesNo=lambda b: bool([print('Yes')] if b else print('No'))
YESNO=lambda b: bool([print('YES')] if b else print('NO'))
int1=lambda x:int(x)-1

N=int(input())
X,Y=[0]*N,[0]*N
dx,dy={},{}
for i in range(N):
    X[i],Y[i]=map(int,input().split())
    if X[i] in dx:
        dx[X[i]].append(i)
    else:
        dx[X[i]]=[i]
    if Y[i] in dy:
        dy[Y[i]].append(i)
    else:
        dy[Y[i]]=[i]
ux,uy=list(set(X)),list(set(Y))
ux.sort()
uy.sort()
uxi={x:i for i,x in enumerate(ux)}
uyi={y:i for i,y in enumerate(uy)}
edge=[[] for i in range(N)]
for i,(x,y) in enumerate(zip(X,Y)):
    for index in dx[x]+dy[y]:
        if index!=i:
            edge[i].append((0,index))
    if uxi[x]>=1:
        nx=ux[uxi[x]-1]
        for index in dx[nx]:
            if index!=i:
                edge[i].append((abs(nx-x),index))
                edge[index].append((abs(nx-x),i))
    if uyi[y]>=1:
        ny=uy[uyi[y]-1]
        for index in dy[ny]:
            if index!=i:
                edge[i].append((abs(ny-y),index))
                edge[index].append((abs(ny-y),i))

def prim(n,edges):
    used=[False]*n
    used[0]=True
    edgelist=[]
    for edge in edges[0]:
        heappush(edgelist,edge)
    cost=0
    while edgelist:
        minedge=heappop(edgelist)
        if used[minedge[1]]:
            continue
        v=minedge[1]
        used[v]=True
        for edge in edges[v]:
            if not used[edge[1]]:
                heappush(edgelist,edge)
        cost+=minedge[0]
    return cost

print(prim(N,edge))


# Optimized solution
# -*- coding: utf-8 -*-
import sys
from heapq import heappush,heappop,heapify
sys.setrecursionlimit(10**9)
INF=10**18
MOD=10**9+7
input=lambda: sys.stdin.readline().rstrip()
YesNo=lambda b: bool([print('Yes')] if b else print('No'))
YESNO=lambda b: bool([print('YES')] if b else print('NO'))
int1=lambda x:int(x)-1

N=int(input())
X,Y=[],[]
for i in range(N):
    x,y=map(int,input().split())
    X.append((y,i))
    Y.append((x,i))
X.sort(key=lambda t:t[0])
Y.sort(key=lambda t:t[0])
edge=[[] for i in range(N)]
for i in range(N-1):
    edge[X[i][1]].append((abs(X[i][0]-X[i+1][0]),X[i+1][1]))
    edge[X[i+1][1]].append((abs(X[i][0]-X[i+1][0]),X[i][1]))
    edge[Y[i][1]].append((abs(Y[i][0]-Y[i+1][0]),Y[i+1][1]))
    edge[Y[i+1][1]].append((abs(Y[i][0]-Y[i+1][0]),Y[i][1]))

def prim(n,edges):
    used=[False]*n
    used[0]=True
    edgelist=[]
    for edge in edges[0]:
        heappush(edgelist,edge)
    cost=0
    while edgelist:
        minedge=heappop(edgelist)
        if used[minedge[1]]:
            continue
        v=minedge[1]
        used[v]=True
        for edge in edges[v]:
            if not used[edge[1]]:
                heappush(edgelist,edge)
        cost+=minedge[0]
    return cost

print(prim(N,edge))
# Original solution
class UF():
  def __init__(self, N):
    self.par = [-1]*N

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

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

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

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

edges = []

sort_x = sorted(coordinates, key=lambda x: x[1])
for i in range(N-1):
  u,v = sort_x[i][0], sort_x[i+1][0]
  edges.append([u,v,abs(sort_x[i][1] - sort_x[i+1][1])])

sort_y = sorted(coordinates, key=lambda x: x[2])
for i in range(N-1):  
  u,v = sort_y[i][0], sort_y[i+1][0]
  edges.append([u,v,abs(sort_y[i][2] - sort_y[i+1][2] )])

edges.sort(key=lambda x: x[2])
uf = UF(N)
res = 0
for u,v,c in edges:
  if not uf.same(u,v):
    uf.union(u,v)
    res += c

print(res)


# Optimized solution
class UF():
  def __init__(self, N):
    self.par = [-1]*N
 
  def find(self, x):
    if self.par[x] < 0:
      return x
    else:
      self.par[x] = self.find(self.par[x])
      return self.par[x]
 
  def union(self, x,y):
    p1,p2 = self.find(x),self.find(y)
    if p1 == p2: return
    if p1 > p2:
      p1,p2 = p2,p1
    self.par[p1] += self.par[p2]
    self.par[p2] = p1
 
  def same(self, x,y):
    return self.find(x) == self.find(y)

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

edges = []

sorted_x = sorted(coords, key=lambda x: x[1])
for i in range(n-1):
  c = abs(sorted_x[i][1] - sorted_x[i+1][1])
  u,v = sorted_x[i][0], sorted_x[i+1][0]
  edges.append((c,u,v))

sorted_y = sorted(coords, key=lambda x: x[2])
for i in range(n-1):
  c = abs(sorted_y[i][2] - sorted_y[i+1][2])
  u,v = sorted_y[i][0], sorted_y[i+1][0]
  edges.append((c,u,v))

edges.sort()

uf = UF(n)
res = 0
for c,u,v in edges:
  if not uf.same(u,v):
    uf.union(u,v)
    res += c
 
print(res)
# Original solution
import sys


class UnionFind():
    def __init__(self, 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


N = int(eval(input()))
Px = []
Py = []
for k, s in enumerate(sys.stdin.readlines()):
    x, y = list(map(int, s.split()))
    Px.append((x, k))
    Py.append((y, k))

edge = []

Px.sort()
Py.sort()
for i in range(N - 1):
    x0, k0 = Px[i]
    x1, k1 = Px[i + 1]
    d = abs(x0 - x1)
    edge.append((d, k0, k1))

    y0, k0 = Py[i]
    y1, k1 = Py[i + 1]
    d = abs(y0 - y1)
    edge.append((d, k0, k1))

edge.sort()
uf = UnionFind(N)
cnt = 0
for d, k0, k1 in edge:
    if uf.find(k0) != uf.find(k1):
        uf.union(k0, k1)
        cnt += d
    
    if uf.parents[uf.find(0)] == -N:
        break

print(cnt)


# Optimized solution
import sys


class UnionFind():
    def __init__(self, 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


N = int(eval(input()))
Px = []
Py = []
for k, s in enumerate(sys.stdin.readlines()):
    x, y = list(map(int, s.split()))
    Px.append((x, k))
    Py.append((y, k))

edge = []

Px.sort()
Py.sort()
for i in range(N - 1):
    x0, k0 = Px[i]
    x1, k1 = Px[i + 1]
    d = abs(x0 - x1)
    edge.append((d, k0, k1))

    y0, k0 = Py[i]
    y1, k1 = Py[i + 1]
    d = abs(y0 - y1)
    edge.append((d, k0, k1))

edge.sort()
uf = UnionFind(N)
cnt = 0
for d, k0, k1 in edge:
    if uf.find(k0) != uf.find(k1):
        uf.union(k0, k1)
        cnt += d

print(cnt)
# Original solution
from collections import defaultdict
import operator

N = eval(input())
xs = []
ys = []
for i in range(N):
    x, y = list(map(int, input().split()))
    xs.append((x,i))
    ys.append((y,i))
xs.sort()
ys.sort()

es = defaultdict(lambda: float('inf'))
for i in range(N-1):
    xd = xs[i+1][0] - xs[i][0]
    i1 = min(xs[i+1][1], xs[i][1])
    i2 = max(xs[i+1][1], xs[i][1])
    es[(i1,i2)] = min(es[(i1,i2)], xd)
    yd = ys[i+1][0] - ys[i][0]
    i3 = min(ys[i+1][1], ys[i][1])
    i4 = max(ys[i+1][1], ys[i][1])
    es[(i3,i4)] = min(es[(i3,i4)], yd)

parent = [i for i in range(N)]
def root(a):
    if parent[a] == a:
        return a
    else:
        parent[a] = root(parent[a])
        return parent[a]
def is_same(a,b):
    return root(a) == root(b)
def unite(a,b):
    ra = root(a)
    rb = root(b)
    if ra == rb: return
    parent[ra] = rb;

value = 0
for k,v in sorted(list(es.items()), key=operator.itemgetter(1)):
    a,b = k
    if is_same(a,b): continue
    unite(a,b)
    value += v
print(value)

# Optimized solution
N = int(eval(input()))
src = [tuple(map(int,input().split())) for i in range(N)]

xs = []
ys = []
for i,(x,y) in enumerate(src):
    xs.append((x,i))
    ys.append((y,i))
xs.sort()
ys.sort()

es = []
for (x1,i1),(x2,i2) in zip(xs,xs[1:]):
    es.append((x2-x1, i1, i2))
for (y1,i1),(y2,i2) in zip(ys,ys[1:]):
    es.append((y2-y1, i1, i2))
es.sort()

class UnionFind:
    def __init__(self,N):
        self.parent = [i for i in range(N)]
        self.rank = [0] * 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.rank[ra] < self.rank[rb]:
            self.parent[ra] = rb
        else:
            self.parent[rb] = ra
            if self.rank[ra] == self.rank[rb]: self.rank[ra] += 1
        self.count += 1

ans = 0
uf = UnionFind(N)
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()))
xys = []
for i in range(N):
  x, y = list(map(int, input().split()))
  xys.append((x, y))
Isx = sorted(list(range(N)), key=lambda i: (xys[i][0], xys[i][1]))
Isy = sorted(list(range(N)), key=lambda i: (xys[i][1], xys[i][0]))
#print(Isx)
#print(Isy)
M = set()
for i in range(N):
  p, q = Isx[i-1], Isx[i]
  a, b = xys[p]
  c, d = xys[q]
  cost = min(abs(a-c), abs(b-d))
  M.add((cost, p, q))
for i in range(N):
  p, q = Isy[i-1], Isy[i]
  a, b = xys[p]
  c, d = xys[q]
  cost = min(abs(a-c), abs(b-d))
  M.add((cost, p, q))
#print(M)
F = [{i} for i in range(N)]
S = list(M)
S.sort(reverse=True)
#print(S)
r = 0
while S:
  cost, p, q = S.pop()
  for i in range(N):
    s = F[i]
    if p in s:
      break
  for j in range(N):
    s = F[j]
    if q in s:
      break
  #print(i, j)
  if i != j:
    r += cost
    s = F[i]|F[j]
    F.pop(max(i, j))
    F.pop(min(i, j))
    F.append(s)
  #print(F)
print(r)


# Optimized solution
N = int(eval(input()))
xys = []
for i in range(N):
  x, y = list(map(int, input().split()))
  xys.append((x, y))
Isx = sorted(list(range(N)), key=lambda i: (xys[i][0], xys[i][1]))
Isy = sorted(list(range(N)), key=lambda i: (xys[i][1], xys[i][0]))
#print(Isx)
#print(Isy)
M = set()
for i in range(1, N):
  p, q = Isx[i-1], Isx[i]
  a, b = xys[p]
  c, d = xys[q]
  cost = min(abs(a-c), abs(b-d))
  M.add((cost, p, q))
for i in range(1, N):
  p, q = Isy[i-1], Isy[i]
  a, b = xys[p]
  c, d = xys[q]
  cost = min(abs(a-c), abs(b-d))
  M.add((cost, p, q))
#print(M)
S = list(M)
S.sort(reverse=True)
#print(S)
r = 0
UF = list(range(N))
def par(m):
  if UF[m] == m:
    return m
  ret = par(UF[m])
  UF[m] = ret
  return ret
while S:
  cost, p, q = S.pop()
  i = par(p)
  j = par(q)
  if i != j:
    r += cost
    UF[i] = j
  #print(UF)
print(r)
# Original solution
from operator import itemgetter
n = int(eval(input()))
x =[]
y =[]
info = [list(map(int,input().split())) for i in range(n)]
for i in range(n):
  x.append([i,info[i][0]])
  y.append([i,info[i][1]])

x = sorted(x,key=itemgetter(1))
y = sorted(y,key=itemgetter(1))
tree = []

for i in range(n-1):
    tree.append([x[i][0],x[i+1][0],x[i+1][1]-x[i][1]])
    tree.append([y[i][0],y[i+1][0],y[i+1][1]-y[i][1]])

#UnionFindクラス
class UnionFind(object):

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

  def find(self, x):
  
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]
  
  # xとyの根を結合させる
  def union(self, x, y):
    x = self.find(x)
    y = self.find(y)
    if x != y:
      if self.rank[x] < self.rank[y]:
        x, y = y, x
      if self.rank[x] == self.rank[y]:
        self.rank[x] += 1
      self.par[y] = x
  
  # x,yの根が同じかどうかを返す（根が同じ:True、根が異なる:False）
  def is_same(self, x, y):
    return self.find(x) == self.find(y)

uf = UnionFind(len(tree))
tree = sorted(tree,key=itemgetter(2))
ans = 0

for i in tree:
  x,y,kyori = i
  if not uf.is_same(x,y):
    uf.union(y,x)
    ans += kyori
print(ans)


# Optimized solution
from operator import itemgetter
n = int(eval(input()))
x =[]
y =[]
info = [list(map(int,input().split())) for i in range(n)]
for i in range(n):
  x.append([i,info[i][0]])
  y.append([i,info[i][1]])

x = sorted(x,key=itemgetter(1))
y = sorted(y,key=itemgetter(1))
tree = []
#for i in range(n):
#  if i==0:
#    tree[x[i][0]].append([x[i+1][0],abs(x[i][1]-x[i+1][1])])
#    tree[y[i][0]].append([y[i+1][0],abs(y[i][1]-y[i+1][1])])
#  elif i==n-1:
#    tree[x[i][0]].append([x[i-1][0],abs(x[i][1]-x[i-1][1])])
#    tree[y[i][0]].append([y[i-1][0],abs(y[i][1]-y[i-1][1])])
#  else:
#    tree[x[i][0]].append([x[i+1][0],abs(x[i][1]-x[i+1][1])])
#    tree[x[i][0]].append([x[i-1][0],abs(x[i][1]-x[i-1][1])])
#    tree[y[i][0]].append([y[i+1][0],abs(y[i][1]-y[i+1][1])])
#    tree[y[i][0]].append([y[i-1][0],abs(y[i][1]-y[i-1][1])])
    
for i in range(n-1):
    tree.append([x[i][0],x[i+1][0],abs(x[i][1]-x[i+1][1])])
    tree.append([y[i][0],y[i+1][0],abs(y[i][1]-y[i+1][1])])

#UnionFindクラス
class UnionFind(object):

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

  def find(self, x):
  
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]
  
  # xとyの根を結合させる
  def union(self, x, y):
    x = self.find(x)
    y = self.find(y)
    if x != y:
      if self.rank[x] < self.rank[y]:
        x, y = y, x
      if self.rank[x] == self.rank[y]:
        self.rank[x] += 1
      self.par[y] = x
  
  # x,yの根が同じかどうかを返す（根が同じ:True、根が異なる:False）
  def is_same(self, x, y):
    return self.find(x) == self.find(y)

uf = UnionFind(len(tree))
tree = sorted(tree,key=itemgetter(2))
ans = 0

for i in tree:
  x,y,kyori = i
  if not uf.is_same(x,y):
    uf.union(y,x)
    ans += kyori
print(ans)
# Original solution
n = int(eval(input()))
x,y = [],[]
for i in range(n):
    a,b = list(map(int,input().split()))
    x.append([a,i])
    y.append([b,i])
x.sort()
y.sort()
g = [[] for _ in range(n)]
for i in range(n-1):
    g[x[i][1]].append([abs(x[i+1][0]-x[i][0]),x[i+1][1]])
    g[x[i+1][1]].append([abs(x[i+1][0]-x[i][0]),x[i][1]])
    g[y[i][1]].append([abs(y[i+1][0]-y[i][0]),y[i+1][1]])
    g[y[i+1][1]].append([abs(y[i+1][0]-y[i][0]),y[i][1]])
import heapq
hq = []
for d,e in g[0]:
    heapq.heappush(hq,[d,e])
cnt = 1
visit = [False]*n
visit[0] = True
ans = 0
while cnt <n:
    cost, end = heapq.heappop(hq)
    if not visit[end]:
        ans += cost
        visit[end] = True
        cnt += 1
        for d,e in g[end]:
            heapq.heappush(hq,[d,e])
print(ans)
        


# Optimized solution
n = int(eval(input()))
x,y = [],[]
for i in range(n):
    a,b = list(map(int,input().split()))
    x.append([a,i])
    y.append([b,i])
x.sort()
y.sort()
g = [[] for _ in range(n)]
for i in range(n-1):
    g[x[i][1]].append([abs(x[i+1][0]-x[i][0]),x[i+1][1]])
    g[x[i+1][1]].append([abs(x[i+1][0]-x[i][0]),x[i][1]])
    g[y[i][1]].append([abs(y[i+1][0]-y[i][0]),y[i+1][1]])
    g[y[i+1][1]].append([abs(y[i+1][0]-y[i][0]),y[i][1]])
import heapq
hq = []
for d,e in g[0]:
    heapq.heappush(hq,[d,e])
cnt = 1
visit = [False]*n
visit[0] = True
ans = 0
while cnt <n:
    cost, end = heapq.heappop(hq)
    if visit[end]: continue
    ans += cost
    visit[end] = True
    cnt += 1
    for d,e in g[end]:
        if not visit[e]:
            heapq.heappush(hq,[d,e])
print(ans)
# Original solution
N = int(eval(input()))
xy = [[int(_) for _ in input().split()] for i in range(N)]

xsort_n = sorted(list(range(N)), key=lambda n:xy[n][0])
ysort_n = sorted(list(range(N)), key=lambda n:xy[n][1])

from collections import defaultdict

neighbors = defaultdict(list)

for i in range(N - 1):
    x1 = xsort_n[i]
    x2 = xsort_n[i+1]
    y1 = ysort_n[i]
    y2 = ysort_n[i+1]
    neighbors[x1].append(x2)
    neighbors[x2].append(x1)
    neighbors[y1].append(y2)
    neighbors[y2].append(y1)

from heapq import *

isused = [0] * N

h = []

heappush(h, (0, 0))

result = 0

while h:
    d, n = heappop(h)
    if isused[n]:
        continue
    result += d
    isused[n] = 1
    for i in neighbors[n]:
        if not isused[i]:
            d1 = min(abs(xy[n][0] - xy[i][0]), abs(xy[n][1] - xy[i][1]))
            heappush(h, (d1, i))
    
print(result)


# Optimized solution
N = int(eval(input()))
xy = [[int(_) for _ in input().split()] for i in range(N)]

xsort_n = sorted(list(range(N)), key=lambda n:xy[n][0])
ysort_n = sorted(list(range(N)), key=lambda n:xy[n][1])

from collections import defaultdict

neighbors = defaultdict(list)

for i in range(N - 1):
    x1 = xsort_n[i]
    x2 = xsort_n[i+1]
    xd = xy[x2][0] - xy[x1][0]
    y1 = ysort_n[i]
    y2 = ysort_n[i+1]
    yd = xy[y2][1] - xy[y1][1]
    neighbors[x1].append((x2, xd))
    neighbors[x2].append((x1, xd))
    neighbors[y1].append((y2, yd))
    neighbors[y2].append((y1, yd))

from heapq import *

isused = [0] * N

h = []

heappush(h, (0, 0))

result = 0

while h:
    d, n = heappop(h)
    if isused[n]:
        continue
    result += d
    isused[n] = 1
    for ni, nd in neighbors[n]:
        if not isused[ni]:
            heappush(h, (nd, ni))
    
print(result)