// 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.3781528531398648x):
#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;

}