stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>



using namespace std;

const int maxN=1e5+5;



int fa[maxN];



struct node

{

    int x,y,id;

}a[maxN],b[maxN];



struct edge

{

    int f,t,w;

}e[maxN*2];



bool cmp1(node x1,node x2)

{

    return x1.x<x2.x;

}



bool cmp2(node x1,node x2)

{

    return x1.y<x2.y;

}



bool cmp3(edge x1,edge x2)

{

    return x1.w<x2.w;

}



int find(int x)

{

    if(fa[x]==-1)return x;

    return fa[x]=find(fa[x]);

}



int uni(int f,int t)

{

    f=find(f);t=find(t);

    if(f==t)return 0;

    fa[f]=t;return 1;

}



int main()

{

    int k,n,cnt=0,now=0;

    long long ans=0;

    memset(fa,-1,sizeof(fa));

    scanf("%d",&n);

    for(k=0;k<n;k++)

    {

        scanf("%d%d",&a[k].x,&a[k].y);

        a[k].id=k;b[k].id=k;

        b[k].x=a[k].x;

        b[k].y=a[k].y;

    }

    sort(a,a+n,cmp1);

    sort(b,b+n,cmp2);

    for(k=1;k<n;k++)

    {

        e[cnt].f=a[k-1].id;

        e[cnt].t=a[k].id;

        e[cnt].w=a[k].x-a[k-1].x;

        cnt++;

    }

    for(k=1;k<n;k++)

    {

        e[cnt].f=b[k-1].id;

        e[cnt].t=b[k].id;

        e[cnt].w=b[k].y-b[k-1].y;

        cnt++;

    }

    sort(e,e+cnt,cmp3);

    for(k=0;k<cnt;k++)

    {

        if(uni(e[k].f,e[k].t))

        {

            ans+=e[k].w;

            now++;

        }

        if(now==n-1)break;

    }

    cout<<ans;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.3848184460764537x):
#include<vector>

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<iostream>

#define rep(i,x,y) for(int i=x;i<=y;++i)



const int INF=1<<30;

using namespace std;



const int maxn=100000+10;



int p[maxn];

int findset(int x){return p[x]==x?x:p[x]=findset(p[x]);}

int merge(int a,int b)

{

	a=findset(a);b=findset(b);

	if(a==b) return 0;

	p[a]=b;return 1;

}



struct Edge{

	int u,v,w;

	Edge(int u=0,int v=0,int w=0):u(u),v(v),w(w){}

	inline bool operator < (const Edge &rhs)const{

		return w<rhs.w;

	}

};



int idx[maxn],idy[maxn],x[maxn],y[maxn];



bool cmpx(int a,int b){return x[a]<x[b];}

bool cmpy(int a,int b){return y[a]<y[b];}



vector<Edge>e;



int main()

{

	int n;cin>>n;

	rep(i,1,n) scanf("%d%d",x+i,y+i),idx[i]=idy[i]=i;

	sort(idx+1,idx+n+1,cmpx);

	sort(idy+1,idy+n+1,cmpy);



	rep(i,1,n-1)

	{

		e.push_back(Edge(idx[i],idx[i+1],x[idx[i+1]]-x[idx[i]]));

		e.push_back(Edge(idy[i],idy[i+1],y[idy[i+1]]-y[idy[i]]));

	}



	sort(e.begin(),e.end());



	rep(i,1,n) p[i]=i;



	int cnt=0;long long cost=0;

	for(int i=0;i<(int)e.size();++i)

	{

	//	printf("(%d,%d,%d)\n",e[i].u,e[i].v,e[i].w);

		if(merge(e[i].u,e[i].v))

		{

			cost+=e[i].w;

			if(--cnt==1) break;

		}

	}



	cout<<cost<<endl;

	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>



using namespace std;



struct point

{

	int x, y, id;

} p[100005];



vector< pair<int, pair<int, int> > > q;



bool cmpx(point a, point b)

{

	if (a.x != b.x) return a.x > b.x;

	else return a.y > b.y;

}



bool cmpy(point a, point b)

{

	if (a.y != b.y) return a.y > b.y;

	else return a.x > b.x;

}



int up[100005];



void makesets()

{

	for (int i = 0; i < 100001; i++)

	{

		up[i] = -1;

	}

}



int Find(int x)

{

	if (up[x] < 0) return x;

	int root = Find(up[x]);

	up[x] = root;

	return root;

}



void Union(int x, int y)

{

	if (Find(x) == Find(y)) return;

	if (up[x] < up[y])

	{

		up[x] += up[y];

		up[y] = x;

	}

	else

	{

		up[y] += up[x];

		up[x] = y;

	}

}



int n;



signed main()

{

	scanf("%d", &n);

	for (int i = 1; i <= n; i++)

	{

		scanf("%d%d", &p[i].x, &p[i].y);

		p[i].id = i;

	}

	sort(p+1, p+1+n, cmpx);

	for (int i = 1; i < n; i++)

	{

		q.push_back(make_pair(p[i].x - p[i+1].x, make_pair(p[i].id, p[i+1].id)));

	}

	sort(p+1, p+1+n, cmpy);

	for (int i = 1; i < n; i++)

	{

		q.push_back(make_pair(p[i].y - p[i+1].y, make_pair(p[i].id, p[i+1].id)));

	}

	sort(q.begin(), q.end());

	makesets();

	long long res = 0;

	for (int i = 0; i < q.size(); i++)

	{

		int u = q[i].second.first, v = q[i].second.second;

		if (Find(u) != Find(v))

		{

			Union(Find(u), Find(v));

			res += q[i].first;

		}

	}

	printf("%lld", res);

}

// Faster C++ solution for the same problem (measured speedup: 1.4135623512574538x):
#include<bits/stdc++.h>

using namespace std;

struct EDGE

{

	int x,y,data;

}edge[2*100000+10];

struct node

{

	int x,y,id;

}arr[100000+10];

int fa[100500];

int find(int x)

{

	if(x==fa[x]) return fa[x];

	return fa[x] = find(fa[x]);

}

bool cmp1(node a,node b)

{

	return a.x<b.x;

}

bool cmp2(node a,node b)

{

	return a.y<b.y;

}

bool cmp(EDGE a,EDGE b)

{

	return a.data<b.data;

}

int cnt = 0;

void built(int x,int y,int data)

{

	edge[++cnt].x=x;

	edge[cnt].y=y;

	edge[cnt].data=data;

}

int main()

{

	int n;

	scanf("%d",&n);

	for(int i=1;i<=n;i++)

	{

		fa[i]=i;

		scanf("%d%d",&arr[i].x,&arr[i].y);

		arr[i].id = i;

	}

	sort(arr+1,arr+1+n,cmp1);

	for(int i=2;i<=n;i++)

	built(arr[i-1].id,arr[i].id,arr[i].x-arr[i-1].x);

	sort(arr+1,arr+1+n,cmp2);

	for(int i=2;i<=n;i++)

	built(arr[i-1].id,arr[i].id,arr[i].y-arr[i-1].y);

	long long res = 0;

	sort(edge+1,edge+1+cnt,cmp);

	for(int i=1;i<=cnt;i++)

	if(find(edge[i].x)!=find(edge[i].y))

	{

		res += edge[i].data;

		fa[fa[edge[i].x]] = fa[edge[i].y];

	}

	printf("%d\n",res);

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define int long long

vector<pair<int,pair<int,int> > >points;

vector<pair<int,pair<int,int> > > edge;

int par[100005];

bool cmp(pair<int,pair<int,int> > &a,pair<int,pair<int,int> > &b ){

	return a.second.first<b.second.first;

}

bool cmp2(pair<int,pair<int,int> > &a,pair<int,pair<int,int> > &b ){

	return a.second.second<b.second.second;

}

void init(){

	for(int i=1;i<=100000;i++){

		par[i]=i;

	}

}

int find(int i){

	if(par[i]==i) return par[i];

	return par[i]=find(par[i]);

}

void dsu(int i,int j){

	par[find(i)]=find(j);

}

bool same(int i,int j){

	return find(i)==find(j);

}

signed main(){

//	freopen("plantree.inp","w",stdin);

//	freopen("plantree.out","r",stdout);

	ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

	int n;

	cin>>n;

	for(int i=1;i<=n;i++){

		int x,y;

		cin>>x>>y;

		points.push_back(make_pair(i,make_pair(x,y)));

	}	

	init();

	sort(points.begin(),points.end(),cmp);

	for(int i=1;i<points.size();i++){

		edge.push_back(make_pair(points[i].second.first-points[i-1].second.first,make_pair(points[i].first,points[i-1].first)));

	}

	sort(points.begin(),points.end(),cmp2);

	for(int i=1;i<points.size();i++){

		edge.push_back(make_pair(points[i].second.second-points[i-1].second.second,make_pair(points[i].first,points[i-1].first)));

	}

	sort(edge.begin(),edge.end());

	int ans=0;

	

	for(int i=0;i<edge.size();i++){

		if(!same(edge[i].second.second,edge[i].second.first)){

			ans+=edge[i].first;

			dsu(edge[i].second.second,edge[i].second.first);

		}

	}

	cout<<ans;

}

// Faster C++ solution for the same problem (measured speedup: 1.8360962591925443x):
#include<bits/stdc++.h>

using namespace std;

struct EDGE

{

	int x,y,data;

}edge[2*100000+10];

struct node

{

	int x,y,id;

}arr[100000+10];

int fa[100500];

int find(int x)

{

	if(x==fa[x]) return fa[x];

	return fa[x] = find(fa[x]);

}

bool cmp1(node a,node b)

{

	return a.x<b.x;

}

bool cmp2(node a,node b)

{

	return a.y<b.y;

}

bool cmp(EDGE a,EDGE b)

{

	return a.data<b.data;

}

int cnt = 0;

void built(int x,int y,int data)

{

	edge[++cnt].x=x;

	edge[cnt].y=y;

	edge[cnt].data=data;

}

int main()

{

	int n;

	scanf("%d",&n);

	for(int i=1;i<=n;i++)

	{

		fa[i]=i;

		scanf("%d%d",&arr[i].x,&arr[i].y);

		arr[i].id = i;

	}

	sort(arr+1,arr+1+n,cmp1);

	for(int i=2;i<=n;i++)

	built(arr[i-1].id,arr[i].id,arr[i].x-arr[i-1].x);

	sort(arr+1,arr+1+n,cmp2);

	for(int i=2;i<=n;i++)

	built(arr[i-1].id,arr[i].id,arr[i].y-arr[i-1].y);

	long long res = 0;

	sort(edge+1,edge+1+cnt,cmp);

	for(int i=1;i<=cnt;i++)

	if(find(edge[i].x)!=find(edge[i].y))

	{

		res += edge[i].data;

		fa[fa[edge[i].x]] = fa[edge[i].y];

	}

	printf("%d\n",res);

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>



using namespace std;

const int maxN=1e5+5;



int fa[maxN];



struct node

{

    int x,y,id;

}a[maxN],b[maxN];



struct edge

{

    int f,t,w;

}e[maxN*2];



bool cmp1(node x1,node x2)

{

    return x1.x<x2.x;

}



bool cmp2(node x1,node x2)

{

    return x1.y<x2.y;

}



bool cmp3(edge x1,edge x2)

{

    return x1.w<x2.w;

}



int find(int x)

{

    if(fa[x]==-1)return x;

    return fa[x]=find(fa[x]);

}



int uni(int f,int t)

{

    f=find(f);t=find(t);

    if(f==t)return 0;

    fa[f]=t;return 1;

}



int main()

{

    int k,n,cnt=0,now=0;

    long long ans=0;

    memset(fa,-1,sizeof(fa));

    scanf("%d",&n);

    for(k=0;k<n;k++)

    {

        scanf("%d%d",&a[k].x,&a[k].y);

        a[k].id=k;b[k].id=k;

        b[k].x=a[k].x;

        b[k].y=a[k].y;

    }

    sort(a,a+n,cmp1);

    sort(b,b+n,cmp2);

    for(k=1;k<n;k++)

    {

        e[cnt].f=a[k-1].id;

        e[cnt].t=a[k].id;

        e[cnt].w=a[k].x-a[k-1].x;

        cnt++;

    }

    for(k=1;k<n;k++)

    {

        e[cnt].f=b[k-1].id;

        e[cnt].t=b[k].id;

        e[cnt].w=b[k].y-b[k-1].y;

        cnt++;

    }

    sort(e,e+cnt,cmp3);

    for(k=0;k<cnt;k++)

    {

        if(uni(e[k].f,e[k].t))

        {

            ans+=e[k].w;

            now++;

        }

        if(now==n-1)break;

    }

    cout<<ans;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.4085499370285477x):
#include<bits/stdc++.h>

using namespace std;

struct EDGE

{

	int x,y,data;

}edge[2*100000+10];

struct node

{

	int x,y,id;

}arr[100000+10];

int fa[100500];

int find(int x)

{

	if(x==fa[x]) return fa[x];

	return fa[x] = find(fa[x]);

}

bool cmp1(node a,node b)

{

	return a.x<b.x;

}

bool cmp2(node a,node b)

{

	return a.y<b.y;

}

bool cmp(EDGE a,EDGE b)

{

	return a.data<b.data;

}

int cnt = 0;

void built(int x,int y,int data)

{

	edge[++cnt].x=x;

	edge[cnt].y=y;

	edge[cnt].data=data;

}

int main()

{

	int n;

	scanf("%d",&n);

	for(int i=1;i<=n;i++)

	{

		fa[i]=i;

		scanf("%d%d",&arr[i].x,&arr[i].y);

		arr[i].id = i;

	}

	sort(arr+1,arr+1+n,cmp1);

	for(int i=2;i<=n;i++)

	built(arr[i-1].id,arr[i].id,arr[i].x-arr[i-1].x);

	sort(arr+1,arr+1+n,cmp2);

	for(int i=2;i<=n;i++)

	built(arr[i-1].id,arr[i].id,arr[i].y-arr[i-1].y);

	long long res = 0;

	sort(edge+1,edge+1+cnt,cmp);

	for(int i=1;i<=cnt;i++)

	if(find(edge[i].x)!=find(edge[i].y))

	{

		res += edge[i].data;

		fa[fa[edge[i].x]] = fa[edge[i].y];

	}

	printf("%d\n",res);

	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>



using namespace std;



struct point

{

	int x, y, id;

} p[100005];



vector< pair<int, pair<int, int> > > q;



bool cmpx(point a, point b)

{

	if (a.x != b.x) return a.x > b.x;

	else return a.y > b.y;

}



bool cmpy(point a, point b)

{

	if (a.y != b.y) return a.y > b.y;

	else return a.x > b.x;

}



int up[100005];



void makesets()

{

	for (int i = 0; i < 100001; i++)

	{

		up[i] = -1;

	}

}



int Find(int x)

{

	if (up[x] < 0) return x;

	int root = Find(up[x]);

	up[x] = root;

	return root;

}



void Union(int x, int y)

{

	if (Find(x) == Find(y)) return;

	if (up[x] < up[y])

	{

		up[x] += up[y];

		up[y] = x;

	}

	else

	{

		up[y] += up[x];

		up[x] = y;

	}

}



int n;



signed main()

{

	scanf("%d", &n);

	for (int i = 1; i <= n; i++)

	{

		scanf("%d%d", &p[i].x, &p[i].y);

		p[i].id = i;

	}

	sort(p+1, p+1+n, cmpx);

	for (int i = 1; i < n; i++)

	{

		q.push_back(make_pair(p[i].x - p[i+1].x, make_pair(p[i].id, p[i+1].id)));

	}

	sort(p+1, p+1+n, cmpy);

	for (int i = 1; i < n; i++)

	{

		q.push_back(make_pair(p[i].y - p[i+1].y, make_pair(p[i].id, p[i+1].id)));

	}

	sort(q.begin(), q.end());

	makesets();

	long long res = 0;

	for (int i = 0; i < q.size(); i++)

	{

		int u = q[i].second.first, v = q[i].second.second;

		if (Find(u) != Find(v))

		{

			Union(Find(u), Find(v));

			res += q[i].first;

		}

	}

	printf("%lld", res);

}

// Faster C++ solution for the same problem (measured speedup: 1.3646021808271298x):
#include <bits/stdc++.h>

#define N 200001

using namespace std;



typedef unsigned ui;

typedef long long ll;

typedef unsigned long long ul;



struct point { int x, y; } ps[N];



ui fs[N];

ui uf(ui x) { return fs[x] ? fs[x] = uf(fs[x]) : x; }

bool uu(ui x, ui y) {

	x = uf(x); y = uf(y);

	if (x != y) fs[x] = y;

	return x != y;

}



ui p[N];



struct edge { ui u, v, w; };

bool operator<(edge e1, edge e2) { return e1.w < e2.w; }

ui dis(ui u, ui v) { return min(abs(ps[u].x - ps[v].x), abs(ps[u].y - ps[v].y)); }



int main(void) {

	ios::sync_with_stdio(0); cin.tie(0);

#ifdef _DEBUG

	ifstream cin("1.in");

#endif

	ui n; cin >> n;

	ul ans = 0;

	for (ui i = 1; i <= n; ++i) cin >> ps[i].x >> ps[i].y;

	iota(p, p + n, 1);

	vector<edge> ev;



	sort(p, p + n, [](ui i1, ui i2) { return ps[i1].x < ps[i2].x; });

	ui i = 0;

	while(i != n - 1) {

		ui u = p[i], v = p[i + 1];

		if (ps[u].x == ps[v].x) uu(u, v);

		else ev.push_back({ u, v, dis(u, v) });

		++i;

	}



	sort(p, p + n, [](ui i1, ui i2) { return ps[i1].y < ps[i2].y; });

	i = 0;

	while(i != n - 1) {

		ui u = p[i], v = p[i + 1];

		if (ps[u].y == ps[v].y) uu(u, v);

		else ev.push_back({ u, v, dis(u, v) });

		++i;

	}



	sort(ev.begin(), ev.end());

	for (edge e : ev)

		if (uu(e.u, e.v))

			ans += e.w;



	cout << ans << endl;

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define int long long

vector<pair<int,pair<int,int> > >points;

vector<pair<int,pair<int,int> > > edge;

int par[100005];

bool cmp(pair<int,pair<int,int> > &a,pair<int,pair<int,int> > &b ){

	return a.second.first<b.second.first;

}

bool cmp2(pair<int,pair<int,int> > &a,pair<int,pair<int,int> > &b ){

	return a.second.second<b.second.second;

}

void init(){

	for(int i=1;i<=100000;i++){

		par[i]=i;

	}

}

int find(int i){

	if(par[i]==i) return par[i];

	return par[i]=find(par[i]);

}

void dsu(int i,int j){

	par[find(i)]=find(j);

}

bool same(int i,int j){

	return find(i)==find(j);

}

signed main(){

//	freopen("plantree.inp","w",stdin);

//	freopen("plantree.out","r",stdout);

	ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

	int n;

	cin>>n;

	for(int i=1;i<=n;i++){

		int x,y;

		cin>>x>>y;

		points.push_back(make_pair(i,make_pair(x,y)));

	}	

	init();

	sort(points.begin(),points.end(),cmp);

	for(int i=1;i<points.size();i++){

		edge.push_back(make_pair(points[i].second.first-points[i-1].second.first,make_pair(points[i].first,points[i-1].first)));

	}

	sort(points.begin(),points.end(),cmp2);

	for(int i=1;i<points.size();i++){

		edge.push_back(make_pair(points[i].second.second-points[i-1].second.second,make_pair(points[i].first,points[i-1].first)));

	}

	sort(edge.begin(),edge.end());

	int ans=0;

	

	for(int i=0;i<edge.size();i++){

		if(!same(edge[i].second.second,edge[i].second.first)){

			ans+=edge[i].first;

			dsu(edge[i].second.second,edge[i].second.first);

		}

	}

	cout<<ans;

}

// Faster C++ solution for the same problem (measured speedup: 1.7725011969042912x):
#include <bits/stdc++.h>

#define N 200001

using namespace std;



typedef unsigned ui;

typedef long long ll;

typedef unsigned long long ul;



struct point { int x, y; } ps[N];



ui fs[N];

ui uf(ui x) { return fs[x] ? fs[x] = uf(fs[x]) : x; }

bool uu(ui x, ui y) {

	x = uf(x); y = uf(y);

	if (x != y) fs[x] = y;

	return x != y;

}



ui p[N];



struct edge { ui u, v, w; };

bool operator<(edge e1, edge e2) { return e1.w < e2.w; }

ui dis(ui u, ui v) { return min(abs(ps[u].x - ps[v].x), abs(ps[u].y - ps[v].y)); }



int main(void) {

	ios::sync_with_stdio(0); cin.tie(0);

#ifdef _DEBUG

	ifstream cin("1.in");

#endif

	ui n; cin >> n;

	ul ans = 0;

	for (ui i = 1; i <= n; ++i) cin >> ps[i].x >> ps[i].y;

	iota(p, p + n, 1);

	vector<edge> ev;



	sort(p, p + n, [](ui i1, ui i2) { return ps[i1].x < ps[i2].x; });

	ui i = 0;

	while(i != n - 1) {

		ui u = p[i], v = p[i + 1];

		if (ps[u].x == ps[v].x) uu(u, v);

		else ev.push_back({ u, v, dis(u, v) });

		++i;

	}



	sort(p, p + n, [](ui i1, ui i2) { return ps[i1].y < ps[i2].y; });

	i = 0;

	while(i != n - 1) {

		ui u = p[i], v = p[i + 1];

		if (ps[u].y == ps[v].y) uu(u, v);

		else ev.push_back({ u, v, dis(u, v) });

		++i;

	}



	sort(ev.begin(), ev.end());

	for (edge e : ev)

		if (uu(e.u, e.v))

			ans += e.w;



	cout << ans << endl;

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>



using namespace std;

const int maxN=1e5+5;



int fa[maxN];



struct node

{

    int x,y,id;

}a[maxN],b[maxN];



struct edge

{

    int f,t,w;

}e[maxN*2];



bool cmp1(node x1,node x2)

{

    return x1.x<x2.x;

}



bool cmp2(node x1,node x2)

{

    return x1.y<x2.y;

}



bool cmp3(edge x1,edge x2)

{

    return x1.w<x2.w;

}



int find(int x)

{

    if(fa[x]==-1)return x;

    return fa[x]=find(fa[x]);

}



int uni(int f,int t)

{

    f=find(f);t=find(t);

    if(f==t)return 0;

    fa[f]=t;return 1;

}



int main()

{

    int k,n,cnt=0,now=0;

    long long ans=0;

    memset(fa,-1,sizeof(fa));

    scanf("%d",&n);

    for(k=0;k<n;k++)

    {

        scanf("%d%d",&a[k].x,&a[k].y);

        a[k].id=k;b[k].id=k;

        b[k].x=a[k].x;

        b[k].y=a[k].y;

    }

    sort(a,a+n,cmp1);

    sort(b,b+n,cmp2);

    for(k=1;k<n;k++)

    {

        e[cnt].f=a[k-1].id;

        e[cnt].t=a[k].id;

        e[cnt].w=a[k].x-a[k-1].x;

        cnt++;

    }

    for(k=1;k<n;k++)

    {

        e[cnt].f=b[k-1].id;

        e[cnt].t=b[k].id;

        e[cnt].w=b[k].y-b[k-1].y;

        cnt++;

    }

    sort(e,e+cnt,cmp3);

    for(k=0;k<cnt;k++)

    {

        if(uni(e[k].f,e[k].t))

        {

            ans+=e[k].w;

            now++;

        }

        if(now==n-1)break;

    }

    cout<<ans;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.3597633766655095x):
#include <bits/stdc++.h>

#define N 200001

using namespace std;



typedef unsigned ui;

typedef long long ll;

typedef unsigned long long ul;



struct point { int x, y; } ps[N];



ui fs[N];

ui uf(ui x) { return fs[x] ? fs[x] = uf(fs[x]) : x; }

bool uu(ui x, ui y) {

	x = uf(x); y = uf(y);

	if (x != y) fs[x] = y;

	return x != y;

}



ui p[N];



struct edge { ui u, v, w; };

bool operator<(edge e1, edge e2) { return e1.w < e2.w; }

ui dis(ui u, ui v) { return min(abs(ps[u].x - ps[v].x), abs(ps[u].y - ps[v].y)); }



int main(void) {

	ios::sync_with_stdio(0); cin.tie(0);

#ifdef _DEBUG

	ifstream cin("1.in");

#endif

	ui n; cin >> n;

	ul ans = 0;

	for (ui i = 1; i <= n; ++i) cin >> ps[i].x >> ps[i].y;

	iota(p, p + n, 1);

	vector<edge> ev;



	sort(p, p + n, [](ui i1, ui i2) { return ps[i1].x < ps[i2].x; });

	ui i = 0;

	while(i != n - 1) {

		ui u = p[i], v = p[i + 1];

		if (ps[u].x == ps[v].x) uu(u, v);

		else ev.push_back({ u, v, dis(u, v) });

		++i;

	}



	sort(p, p + n, [](ui i1, ui i2) { return ps[i1].y < ps[i2].y; });

	i = 0;

	while(i != n - 1) {

		ui u = p[i], v = p[i + 1];

		if (ps[u].y == ps[v].y) uu(u, v);

		else ev.push_back({ u, v, dis(u, v) });

		++i;

	}



	sort(ev.begin(), ev.end());

	for (edge e : ev)

		if (uu(e.u, e.v))

			ans += e.w;



	cout << ans << endl;

	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>



using namespace std;



struct point

{

	int x, y, id;

} p[100005];



vector< pair<int, pair<int, int> > > q;



bool cmpx(point a, point b)

{

	if (a.x != b.x) return a.x > b.x;

	else return a.y > b.y;

}



bool cmpy(point a, point b)

{

	if (a.y != b.y) return a.y > b.y;

	else return a.x > b.x;

}



int up[100005];



void makesets()

{

	for (int i = 0; i < 100001; i++)

	{

		up[i] = -1;

	}

}



int Find(int x)

{

	if (up[x] < 0) return x;

	int root = Find(up[x]);

	up[x] = root;

	return root;

}



void Union(int x, int y)

{

	if (Find(x) == Find(y)) return;

	if (up[x] < up[y])

	{

		up[x] += up[y];

		up[y] = x;

	}

	else

	{

		up[y] += up[x];

		up[x] = y;

	}

}



int n;



signed main()

{

	scanf("%d", &n);

	for (int i = 1; i <= n; i++)

	{

		scanf("%d%d", &p[i].x, &p[i].y);

		p[i].id = i;

	}

	sort(p+1, p+1+n, cmpx);

	for (int i = 1; i < n; i++)

	{

		q.push_back(make_pair(p[i].x - p[i+1].x, make_pair(p[i].id, p[i+1].id)));

	}

	sort(p+1, p+1+n, cmpy);

	for (int i = 1; i < n; i++)

	{

		q.push_back(make_pair(p[i].y - p[i+1].y, make_pair(p[i].id, p[i+1].id)));

	}

	sort(q.begin(), q.end());

	makesets();

	long long res = 0;

	for (int i = 0; i < q.size(); i++)

	{

		int u = q[i].second.first, v = q[i].second.second;

		if (Find(u) != Find(v))

		{

			Union(Find(u), Find(v));

			res += q[i].first;

		}

	}

	printf("%lld", res);

}

// Faster C++ solution for the same problem (measured speedup: 1.392274141243218x):
#include<bits/stdc++.h>

#pragma O3

using namespace std;

struct node{

	int v,l,r;

};

struct no{

	int x,y,p;

};

struct cmp1{

	bool operator()(no a,no b){

		if(a.x!=b.x) return a.x<b.x;

		if(a.y!=b.y) return a.y<b.y;

		return a.p<b.p;

	}

};

struct cmp2{

	bool operator()(no a,no b){

		if(a.y!=b.y)return a.y<b.y;

		if(a.x!=b.x) return a.x<b.x;

		return a.p<b.p;

	}

};

struct cmppq{

	bool operator()(node a,node b){

		if(a.v!=b.v) return a.v>b.v;

		if(a.l!=b.l) return a.l>b.l;

		return a.r>b.r;

	}

};

vector<no> r;

priority_queue<node,vector<node>,cmppq> pq;

int par[100004];

int Find(int x){

	if(x!=par[x]) par[x]=Find(par[x]);

	return par[x];

}

void Union(int x,int y){

	int px=Find(x);

	int py=Find(y);

	if(px!=py) par[py]=px;

}

signed main(){

//	freopen(".inp","r",stdin);

//	freopen(".out","w",stdout);

//	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	int n,u,v,tmp,ans=0;

	cin>>n;

	for(int i=0;i<n;i++){

		cin>>u>>v;

		r.push_back({u,v,i});

		par[i]=i;

	}

	sort(r.begin(),r.end(),cmp1());

	for(int i=0;i<n-1;i++){

		tmp=min(abs(r[i].x-r[i+1].x),abs(r[i].y-r[i+1].y));

		pq.push({tmp,r[i].p,r[i+1].p});

	}

	sort(r.begin(),r.end(),cmp2());

	for(int i=0;i<n-1;i++){

		tmp=min(abs(r[i].x-r[i+1].x),abs(r[i].y-r[i+1].y));

		pq.push({tmp,r[i].p,r[i+1].p});

	}

	while(!pq.empty()){

		u=pq.top().l;

		v=pq.top().r;

		if(Find(u)!=Find(v)){

			ans+=pq.top().v;

			Union(u,v);

		}

		pq.pop();

	}

	cout<<ans;

}