// 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.3782503431260085x):
#define _CRT_SECURE_NO_DEPRECATE

#pragma comment(linker, "/STACK:102400000,102400000")

#include<iostream>  

#include<cstdio>  

#include<fstream>  

#include<iomanip>

#include<algorithm>  

#include<cmath>  

#include<deque>  

#include<vector>  

#include<assert.h>

#include<bitset>

#include<queue>  

#include<string>  

#include<cstring>  

#include<map>  

#include<stack>  

#include<set>

#include<functional>

#define pii pair<int, int>

#define mod 1000000007

#define mp make_pair

#define pi acos(-1)

#define eps 0.00000001

#define mst(a,i) memset(a,i,sizeof(a))

#define all(n) n.begin(),n.end()

#define lson(x) ((x<<1))  

#define rson(x) ((x<<1)|1) 

#define inf 0x3f3f3f3f

typedef long long ll;

typedef unsigned long long ull;

using namespace std;

const int maxn = 1e5 + 5;

class node {

public:

    int u, v, w;

    node(int a, int b, int c) :u(a), v(b), w(c) {};

};

int fa[maxn];

int getf(int i) { return i == fa[i] ? i : fa[i] = getf(fa[i]); }

vector<node>edge;

bool cmp(const node&a, const node&b){return a.w < b.w;}

class T {

public:

    int value, id;

    bool operator<(const T &a){return value < a.value;}

};

T sx[maxn], sy[maxn];

int main()

{

    ios::sync_with_stdio(false);

    cin.tie(0);

    int i, j, k, m, n, ta, tb;

    cin >> n;

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

        fa[i] = i;

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

    {

        cin >> sx[i].value >> sy[i].value;

        sx[i].id = sy[i].id = i;

    }

    sort(sx + 1, sx + n + 1);

    sort(sy + 1, sy + 1 + n);

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

    {

        edge.push_back(node(sx[i].id, sx[i + 1].id, sx[i+1].value - sx[i].value));

        edge.push_back(node(sy[i].id, sy[i + 1].id, sy[i+1].value - sy[i].value));

    }

    sort(all(edge), cmp);

    ll ans = 0;

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

    {

        if (getf(edge[i].u) != getf(edge[i].v))

        {

           ans += edge[i].w;

           fa[getf(edge[i].u)] = getf(edge[i].v);

        }

    }

    cout << ans << endl;

    return 0;

}