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

#include<fstream>

#include<sstream>

#include<algorithm>

#include<cstdio>

#include<cassert>

#include<cmath>

#include<cstdlib>

#include<cstring>

#include<string>

#include<deque>

#include<queue>

#include<vector>

#include<list>

#include<map>

#include<set>

#include<bitset>

#include<stack>

#include<iomanip>

#include<utility>

#include<functional>

using namespace std;

int n,m;

int ans;

int par[100005];

vector<int> edge[100005];

vector<pair<int,int> > el;

pair<int,int> e[200005];

pair<pair<int,int>,int> a[100005],b[100005];

int find(int x)

{

	if(par[x]!=x)

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

	else

		return par[x];

}

bool unite(int x,int y)

{

	x=find(x);

	y=find(y);

	if(x==y)

		return false;

	else

	{

		par[x]=y;

		return true;

	}

}

int main()

{

	cin>>n;

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

	{

		cin>>a[i].first.first>>a[i].first.second;

		b[i].first.first=a[i].first.second;

		b[i].first.second=a[i].first.first;

		a[i].second=b[i].second=i;

	}

	sort(a,a+n);

	sort(b,b+n);

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

	{

		edge[a[i].second].push_back(a[i-1].second);

		e[m]=make_pair(a[i].second,a[i-1].second);

		el.push_back(make_pair(a[i].first.first-a[i-1].first.first,m++));

	}

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

	{

		edge[b[i].second].push_back(b[i-1].second);

		e[m]=make_pair(b[i].second,b[i-1].second);

		el.push_back(make_pair(b[i].first.first-b[i-1].first.first,m++));

	}

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

		par[i]=i;

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

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

	{

		int xx=e[el[i].second].first;

		int yy=e[el[i].second].second;

		if(unite(xx,yy))

			ans+=el[i].first;

	}

	cout<<ans;

	return 0;

}


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

#define int long long

#define mod 1000000007

#define lim 100001

using namespace std;

struct point

{

	int x,y,id;

} c[lim];

struct edge

{

	int u,v,cost;

} e[2*lim];

bool cmp1(point a,point b)

{

	return a.x < b.x;

}

bool cmp2(point a,point b)

{

	return a.y < b.y;

}

bool cmp(edge a,edge b)

{

	return a.cost < b.cost;

}

int p[lim];

int dx[lim],dy[lim];

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

int n,tot;

signed main()

{

  ios::sync_with_stdio(false);

  cin.tie(0);cout.tie(0);

  cin >> n;

  for(int i = 0; i <= n; i++) p[i] = i;

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

   cin >> dx[i] >> dy[i];

  }

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

  {

    c[i].x = dx[i]; c[i].y = dy[i];c[i].id = i;

  }

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

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

    e[tot].u = c[i].id;

    e[tot].v = c[i-1].id;

    e[tot].cost = c[i].x - c[i-1].x;

    tot++;

  }

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

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

    e[tot].u = c[i].id;

    e[tot].v = c[i-1].id;

    e[tot].cost = c[i].y - c[i-1].y;

    tot++;

  }

  sort(e,e+tot,cmp);

  int ans = 0;

  int cnt = 0;

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

    int f = find(e[i].u);

    int t = find(e[i].v);

    if(f!=t){ans+=e[i].cost;p[f] = t;cnt++;}

    if(cnt == n-1) break;

  }

  cout << ans;

  return 0;

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

using namespace std;



#define fi first

#define se second

const int inf = 1e9 + 7;

int n, par[100010], ans = 0;

pair <pair <int, int>, int> a[100010]; bool dis[100010];

priority_queue<pair <int, pair <int, int> >, vector<pair <int, pair <int, int> > >, greater<pair <int, pair <int, int> > > > wl1, wl2;

int find(int a) {

	return (par[a] < 0 ? a : par[a] = find(par[a]));

}

void unionset(int a, int b) {

	int c = find(a), d = find(b);

	if(par[c] < par[d]) par[c] += par[d], par[d] = c;

	else par[d] += par[c], par[c] = d;

}

int main() {

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

	scanf("%d", &n);

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

		scanf("%d%d", &a[i].fi.fi, &a[i].fi.se);

		a[i].se = i;

	}

	sort(a, a + n);

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

		wl1.push({a[i+1].fi.fi - a[i].fi.fi, {a[i].se, a[i+1].se}});

		swap(a[i].fi.fi, a[i].fi.se);

	}

	swap(a[n-1].fi.fi, a[n-1].fi.se);

	sort(a, a + n);

	for(int i = 0; i < n-1; i++) wl2.push({a[i+1].fi.fi - a[i].fi.fi, {a[i].se, a[i+1].se}});

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

		while(find(wl1.top().se.fi) == find(wl1.top().se.se)) wl1.pop();

		while(find(wl2.top().se.fi) == find(wl2.top().se.se)) wl2.pop();

		int d1 = inf, d2 = inf, u1, u2, v1, v2;

		if(not wl1.empty()) d1 = wl1.top().fi, u1 = wl1.top().se.fi, v1 = wl1.top().se.se;

		if(not wl2.empty()) d2 = wl2.top().fi, u2 = wl2.top().se.fi, v2 = wl2.top().se.se;

		if(d1 < d2) {

			unionset(u1, v1);

			ans += d1;

		}

		else {

			unionset(u2, v2);

			ans += d2;

		}

	}

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

}

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

#define int long long

#define mod 1000000007

#define lim 100001

using namespace std;

struct point

{

	int x,y,id;

} c[lim];

struct edge

{

	int u,v,cost;

} e[2*lim];

bool cmp1(point a,point b)

{

	return a.x < b.x;

}

bool cmp2(point a,point b)

{

	return a.y < b.y;

}

bool cmp(edge a,edge b)

{

	return a.cost < b.cost;

}

int p[lim];

int dx[lim],dy[lim];

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

int n,tot;

signed main()

{

  ios::sync_with_stdio(false);

  cin.tie(0);cout.tie(0);

  cin >> n;

  for(int i = 0; i <= n; i++) p[i] = i;

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

   cin >> dx[i] >> dy[i];

  }

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

  {

    c[i].x = dx[i]; c[i].y = dy[i];c[i].id = i;

  }

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

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

    e[tot].u = c[i].id;

    e[tot].v = c[i-1].id;

    e[tot].cost = c[i].x - c[i-1].x;

    tot++;

  }

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

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

    e[tot].u = c[i].id;

    e[tot].v = c[i-1].id;

    e[tot].cost = c[i].y - c[i-1].y;

    tot++;

  }

  sort(e,e+tot,cmp);

  int ans = 0;

  int cnt = 0;

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

    int f = find(e[i].u);

    int t = find(e[i].v);

    if(f!=t){ans+=e[i].cost;p[f] = t;cnt++;}

    if(cnt == n-1) break;

  }

  cout << ans;

  return 0;

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

#include<fstream>

#include<sstream>

#include<algorithm>

#include<cstdio>

#include<cassert>

#include<cmath>

#include<cstdlib>

#include<cstring>

#include<string>

#include<deque>

#include<queue>

#include<vector>

#include<list>

#include<map>

#include<set>

#include<bitset>

#include<stack>

#include<iomanip>

#include<utility>

#include<functional>

using namespace std;

int n,m;

int ans;

int par[100005];

vector<int> edge[100005];

vector<pair<int,int> > el;

pair<int,int> e[200005];

pair<pair<int,int>,int> a[100005],b[100005];

int find(int x)

{

	if(par[x]!=x)

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

	else

		return par[x];

}

bool unite(int x,int y)

{

	x=find(x);

	y=find(y);

	if(x==y)

		return false;

	else

	{

		par[x]=y;

		return true;

	}

}

int main()

{

	cin>>n;

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

	{

		cin>>a[i].first.first>>a[i].first.second;

		b[i].first.first=a[i].first.second;

		b[i].first.second=a[i].first.first;

		a[i].second=b[i].second=i;

	}

	sort(a,a+n);

	sort(b,b+n);

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

	{

		edge[a[i].second].push_back(a[i-1].second);

		e[m]=make_pair(a[i].second,a[i-1].second);

		el.push_back(make_pair(a[i].first.first-a[i-1].first.first,m++));

	}

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

	{

		edge[b[i].second].push_back(b[i-1].second);

		e[m]=make_pair(b[i].second,b[i-1].second);

		el.push_back(make_pair(b[i].first.first-b[i-1].first.first,m++));

	}

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

		par[i]=i;

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

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

	{

		int xx=e[el[i].second].first;

		int yy=e[el[i].second].second;

		if(unite(xx,yy))

			ans+=el[i].first;

	}

	cout<<ans;

	return 0;

}


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

#define int long long

using namespace std;



struct point {

    int x, y, id;

} p[100001];



struct edge_list {

    int w, u, v;

    bool operator < (const edge_list &o) const {

        return w < o.w;

    }

};



int n, ans = 0, up[100001];

vector <edge_list> edge;



int union_find(int u) {

    if(u == up[u]) {

        return u;

    }

    return up[u] = union_find(up[u]);

}



void union_merge(int u, int v) {

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

        up[union_find(u)] = union_find(v);

    }

}



signed main() {

    scanf("%lld", &n);

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

        up[i] = i;

    }

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

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

        p[i].id = i;

    }

    sort(p + 1, p + n + 1, [](point a, point b) {

        return a.x < b.x;

    });

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

        edge.push_back({p[i + 1].x - p[i].x, p[i].id, p[i + 1].id});

    }

    sort(p + 1, p + n + 1, [](point a, point b) {

        return a.y < b.y;

    });

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

        edge.push_back({p[i + 1].y - p[i].y, p[i].id, p[i + 1].id});

    }

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

    for(auto x : edge) {

        int u = x.u, v = x.v, w = x.w;

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

            union_merge(u, v);

            ans += w;

        }

    }

    printf("%lld\n", ans);

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

using namespace std;



#define fi first

#define se second

const int inf = 1e9 + 7;

int n, par[100010], ans = 0;

pair <pair <int, int>, int> a[100010]; bool dis[100010];

priority_queue<pair <int, pair <int, int> >, vector<pair <int, pair <int, int> > >, greater<pair <int, pair <int, int> > > > wl1, wl2;

int find(int a) {

	return (par[a] < 0 ? a : par[a] = find(par[a]));

}

void unionset(int a, int b) {

	int c = find(a), d = find(b);

	if(par[c] < par[d]) par[c] += par[d], par[d] = c;

	else par[d] += par[c], par[c] = d;

}

int main() {

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

	scanf("%d", &n);

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

		scanf("%d%d", &a[i].fi.fi, &a[i].fi.se);

		a[i].se = i;

	}

	sort(a, a + n);

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

		wl1.push({a[i+1].fi.fi - a[i].fi.fi, {a[i].se, a[i+1].se}});

		swap(a[i].fi.fi, a[i].fi.se);

	}

	swap(a[n-1].fi.fi, a[n-1].fi.se);

	sort(a, a + n);

	for(int i = 0; i < n-1; i++) wl2.push({a[i+1].fi.fi - a[i].fi.fi, {a[i].se, a[i+1].se}});

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

		while(find(wl1.top().se.fi) == find(wl1.top().se.se)) wl1.pop();

		while(find(wl2.top().se.fi) == find(wl2.top().se.se)) wl2.pop();

		int d1 = inf, d2 = inf, u1, u2, v1, v2;

		if(not wl1.empty()) d1 = wl1.top().fi, u1 = wl1.top().se.fi, v1 = wl1.top().se.se;

		if(not wl2.empty()) d2 = wl2.top().fi, u2 = wl2.top().se.fi, v2 = wl2.top().se.se;

		if(d1 < d2) {

			unionset(u1, v1);

			ans += d1;

		}

		else {

			unionset(u2, v2);

			ans += d2;

		}

	}

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

}

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

#define int long long

using namespace std;



struct point {

    int x, y, id;

} p[100001];



struct edge_list {

    int w, u, v;

    bool operator < (const edge_list &o) const {

        return w < o.w;

    }

};



int n, ans = 0, up[100001];

vector <edge_list> edge;



int union_find(int u) {

    if(u == up[u]) {

        return u;

    }

    return up[u] = union_find(up[u]);

}



void union_merge(int u, int v) {

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

        up[union_find(u)] = union_find(v);

    }

}



signed main() {

    scanf("%lld", &n);

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

        up[i] = i;

    }

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

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

        p[i].id = i;

    }

    sort(p + 1, p + n + 1, [](point a, point b) {

        return a.x < b.x;

    });

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

        edge.push_back({p[i + 1].x - p[i].x, p[i].id, p[i + 1].id});

    }

    sort(p + 1, p + n + 1, [](point a, point b) {

        return a.y < b.y;

    });

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

        edge.push_back({p[i + 1].y - p[i].y, p[i].id, p[i + 1].id});

    }

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

    for(auto x : edge) {

        int u = x.u, v = x.v, w = x.w;

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

            union_merge(u, v);

            ans += w;

        }

    }

    printf("%lld\n", ans);

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



using namespace std;



const int N = 2e5 + 5;



struct point {

    int x, y, id;

} a[N];



bool cmp1(const point& a, const point& b) {

    if (a.x != b.x) {

        return a.x < b.x;

    }

    return a.y < b.y;

}



bool cmp2(const point& a, const point& b) {

    if (a.y != b.y) {

        return a.y < b.y;

    }

    return a.x < b.x;

}



int n;

bool visited[N];

vector<pair<long long, int> > g[N];



long long prim(int x) {

    priority_queue<pair<long long, int>, vector<pair<long long, int> >, greater<pair<long long, int> > > pq;

    long long ans = 0;

    pq.push({0, x});

    while(!pq.empty()) {

        pair<long long, int> p = pq.top();

        pq.pop();

        x = p.second;

        if (visited[x]) {

        	continue;

		}

        ans += p.first;

        visited[x] = true;

        for(int i = 0; i < g[x].size(); i++) {

            int y = g[x][i].second;

            if (!visited[y]) {

            	pq.push(g[x][i]);

            }

        }

    }

    return ans;

}



int main() {

	ios::sync_with_stdio(false);

	cin.tie(nullptr);

	cin >> n;

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

		cin >> a[i].x >> a[i].y;

		a[i].id = i + 1;

	}

	sort(a, a + n, cmp1);

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

		g[a[i].id].push_back({abs(a[i].x - a[i - 1].x), a[i - 1].id});

		g[a[i - 1].id].push_back({abs(a[i].x - a[i - 1].x), a[i].id});

	}

	sort(a, a + n, cmp2);

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

		g[a[i].id].push_back({abs(a[i].y - a[i - 1].y), a[i - 1].id});

		g[a[i - 1].id].push_back({abs(a[i].y - a[i - 1].y), a[i].id});

	}

	cout << prim(1) << '\n';

	return 0;

}


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

#define int long long

using namespace std;



struct point {

    int x, y, id;

} p[100001];



struct edge_list {

    int w, u, v;

    bool operator < (const edge_list &o) const {

        return w < o.w;

    }

};



int n, ans = 0, up[100001];

vector <edge_list> edge;



int union_find(int u) {

    if(u == up[u]) {

        return u;

    }

    return up[u] = union_find(up[u]);

}



void union_merge(int u, int v) {

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

        up[union_find(u)] = union_find(v);

    }

}



signed main() {

    scanf("%lld", &n);

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

        up[i] = i;

    }

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

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

        p[i].id = i;

    }

    sort(p + 1, p + n + 1, [](point a, point b) {

        return a.x < b.x;

    });

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

        edge.push_back({p[i + 1].x - p[i].x, p[i].id, p[i + 1].id});

    }

    sort(p + 1, p + n + 1, [](point a, point b) {

        return a.y < b.y;

    });

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

        edge.push_back({p[i + 1].y - p[i].y, p[i].id, p[i + 1].id});

    }

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

    for(auto x : edge) {

        int u = x.u, v = x.v, w = x.w;

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

            union_merge(u, v);

            ans += w;

        }

    }

    printf("%lld\n", ans);

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



using namespace std;

using ll = long long;



const int N = 2e5 + 5;



struct point {

    int x, y, id;

} a[N];



bool cmp1(const point& a, const point& b) {

    if (a.x != b.x) {

        return a.x < b.x;

    }

    return a.y < b.y;

}



bool cmp2(const point& a, const point& b) {

    if (a.y != b.y) {

        return a.y < b.y;

    }

    return a.x < b.x;

}



int n;

bool visited[N];

vector<pair<ll, int> > g[N];



ll prim(int x) {

    priority_queue<pair<ll, int>, vector<pair<ll, int> >, greater<pair<ll, int> > > pq;

    ll ans = 0;

    pq.push({0, x});

    while(!pq.empty()) {

        pair<ll, int> p = pq.top();

        pq.pop();

        x = p.second;

        if (visited[x]) {

        	continue;

		}

        ans += p.first;

        visited[x] = true;

        for(int i = 0; i < g[x].size(); i++) {

            int y = g[x][i].second;

            if (!visited[y]) {

            	pq.push(g[x][i]);

            }

        }

    }

    return ans;

}



int main() {

	ios::sync_with_stdio(false);

	cin.tie(nullptr);

	cin >> n;

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

		cin >> a[i].x >> a[i].y;

		a[i].id = i + 1;

	}

	sort(a, a + n, cmp1);

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

		g[a[i].id].push_back({abs(a[i].x - a[i - 1].x), a[i - 1].id});

		g[a[i - 1].id].push_back({abs(a[i].x - a[i - 1].x), a[i].id});

	}

	sort(a, a + n, cmp2);

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

		g[a[i].id].push_back({abs(a[i].y - a[i - 1].y), a[i - 1].id});

		g[a[i - 1].id].push_back({abs(a[i].y - a[i - 1].y), a[i].id});

	}

	cout << prim(1) << '\n';

	return 0;

}


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

#define int long long

using namespace std;



struct point {

    int x, y, id;

} p[100001];



struct edge_list {

    int w, u, v;

    bool operator < (const edge_list &o) const {

        return w < o.w;

    }

};



int n, ans = 0, up[100001];

vector <edge_list> edge;



int union_find(int u) {

    if(u == up[u]) {

        return u;

    }

    return up[u] = union_find(up[u]);

}



void union_merge(int u, int v) {

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

        up[union_find(u)] = union_find(v);

    }

}



signed main() {

    scanf("%lld", &n);

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

        up[i] = i;

    }

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

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

        p[i].id = i;

    }

    sort(p + 1, p + n + 1, [](point a, point b) {

        return a.x < b.x;

    });

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

        edge.push_back({p[i + 1].x - p[i].x, p[i].id, p[i + 1].id});

    }

    sort(p + 1, p + n + 1, [](point a, point b) {

        return a.y < b.y;

    });

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

        edge.push_back({p[i + 1].y - p[i].y, p[i].id, p[i + 1].id});

    }

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

    for(auto x : edge) {

        int u = x.u, v = x.v, w = x.w;

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

            union_merge(u, v);

            ans += w;

        }

    }

    printf("%lld\n", ans);

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

using namespace std;

#define MAX 300000

#define int long long

struct Pair{

	int x,y, id;

};

int n;

Pair a[MAX+1];

typedef Pair PP;

typedef pair<int,int> pp;

vector<pair<int,int> > G[MAX+1];

bool cmp(PP a,PP b){return a.x<b.x;};

bool CMP(PP a,PP b){return a.y<b.y;};

bool visited[MAX+1];

int ans;

#define fi first

#define se second

void DJK(int x){

	ans = 0;

	priority_queue<pp,vector<pp> ,greater<pp> >pq;

	pq.push({0,x});

	while(!pq.empty()){

		int u = pq.top().se;

		int w = pq.top().fi;

		pq.pop();

		if(visited[u]) continue;

		ans+=w;

		visited[u] = 1;

		for(pp ii : G[u]){

			int v = ii.se;

			pq.push({ii.fi,v});

		}

	}

}

signed main(){

	cin >> n;

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

		cin >> a[i].x >> a[i].y;

		a[i].id = i;

	}

	sort(a+1,a+n+1,cmp);

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

		G[a[i].id].push_back({a[i].x-a[i-1].x,a[i-1].id});

		G[a[i-1].id].push_back({a[i].x-a[i-1].x,a[i].id});

	}

	sort(a+1,a+n+1,CMP);

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

		G[a[i].id].push_back({a[i].y-a[i-1].y,a[i-1].id});

		G[a[i-1].id].push_back({a[i].y-a[i-1].y,a[i].id});

	}

	DJK(1);

	cout << ans;

}

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

#define int long long

using namespace std;



struct point {

    int x, y, id;

} p[100001];



struct edge_list {

    int w, u, v;

    bool operator < (const edge_list &o) const {

        return w < o.w;

    }

};



int n, ans = 0, up[100001];

vector <edge_list> edge;



int union_find(int u) {

    if(u == up[u]) {

        return u;

    }

    return up[u] = union_find(up[u]);

}



void union_merge(int u, int v) {

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

        up[union_find(u)] = union_find(v);

    }

}



signed main() {

    scanf("%lld", &n);

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

        up[i] = i;

    }

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

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

        p[i].id = i;

    }

    sort(p + 1, p + n + 1, [](point a, point b) {

        return a.x < b.x;

    });

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

        edge.push_back({p[i + 1].x - p[i].x, p[i].id, p[i + 1].id});

    }

    sort(p + 1, p + n + 1, [](point a, point b) {

        return a.y < b.y;

    });

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

        edge.push_back({p[i + 1].y - p[i].y, p[i].id, p[i + 1].id});

    }

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

    for(auto x : edge) {

        int u = x.u, v = x.v, w = x.w;

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

            union_merge(u, v);

            ans += w;

        }

    }

    printf("%lld\n", ans);

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

using namespace std;

#define MAX 300000

#define int long long

struct Pair{

	int x,y, id;

};

int n;

Pair a[MAX+1];

typedef Pair PP;

typedef pair<int,int> pp;

vector<pair<int,int> > G[MAX+1];

bool cmp(PP a,PP b){return a.x<b.x;};

bool CMP(PP a,PP b){return a.y<b.y;};

bool visited[MAX+1];

int ans;

#define fi first

#define se second

void DJK(int x){

	ans = 0;

	priority_queue<pp,vector<pp> ,greater<pp> >pq;

	pq.push({0,x});

	while(!pq.empty()){

		int u = pq.top().se;

		int w = pq.top().fi;

		pq.pop();

		if(visited[u]) continue;

		ans+=w;

		visited[u] = 1;

		for(pp ii : G[u]){

			int v = ii.se;

			pq.push({ii.fi,v});

		}

	}

}

signed main(){

	cin >> n;

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

		cin >> a[i].x >> a[i].y;

		a[i].id = i;

	}

	sort(a+1,a+n+1,cmp);

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

		G[a[i].id].push_back({a[i].x-a[i-1].x,a[i-1].id});

		G[a[i-1].id].push_back({a[i].x-a[i-1].x,a[i].id});

	}

	sort(a+1,a+n+1,CMP);

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

		G[a[i].id].push_back({a[i].y-a[i-1].y,a[i-1].id});

		G[a[i-1].id].push_back({a[i].y-a[i-1].y,a[i].id});

	}

	DJK(1);

	cout << ans;

}

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



using namespace std;

#define ll long long

#define f first

#define s second

ll n,x,y,tmp,ans;



int par[100005] , sz[100005];



int findPar(int node)

{

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

    return par[node] = findPar(par[node]);

}



void mergeCom(int node , int node2)

{

    int led = findPar(node) , led2 = findPar(node2);



    if (sz[led] > sz[led2])

    {

        par[led2]=led , sz[led] += sz[led2];

    }

    else

    {

        par[led]=led2 , sz[led2] += sz[led];

    }

}



int main()

{

    cin >> n;

    pair < pair<ll,ll> , ll> arr[n+1] , arr2[n+1];

    vector <pair<ll , pair<ll,ll> > > vec;



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

    {

        cin >> x >> y;

        arr[i].f.f=x , arr[i].f.s=y , arr[i].s=i;

        arr2[i].f.f=y , arr2[i].f.s=x , arr2[i].s=i;

        par[i]=i , sz[i]=1;

    }

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

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

    {

        tmp = min(abs(arr[i+1].f.f-arr[i].f.f) , abs(arr[i+1].f.s-arr[i].f.s));

        vec.push_back({tmp , {arr[i+1].s , arr[i].s}});



        tmp = min(abs(arr2[i+1].f.f-arr2[i].f.f) , abs(arr2[i+1].f.s-arr2[i].f.s));

        vec.push_back({tmp , {arr2[i+1].s , arr2[i].s}});

    }



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

    tmp = n-1;

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

    {

        if (!tmp) break;

        x = vec[i].s.f , y = vec[i].s.s;

        if (findPar(x)==findPar(y)) continue;

        ans += vec[i].f , tmp--;

        mergeCom(vec[i].s.f , vec[i].s.s);

    }

    cout << ans << "\n";



    return 0;

}