// 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.4106397391918637x):
/*

    _____

  .'|||||'.

 /  >   <  \

|     ^     |

|  \     /  |

 \  '---'  /

  '._____.'

    |||||

*/



#include<iostream>

#include<string>

#include<algorithm>

#include<cstdlib>

#include<cstdio>

#include<set>

#include<map>

#include<vector>

#include<cstring>

#include<stack>

#include<cmath>

#include<queue>

using namespace std;

#define CL(x,v); memset(x,v,sizeof(x));

#define INF 0x3f3f3f3f

#define LL long long

#define REP(i,r,n) for(int i=r;i<=n;i++)

#define RREP(i,n,r) for(int i=n;i>=r;i--)

struct part{

LL v;

int id;

};

struct part1{

int x,y;

LL v;

};

bool cmp(struct part a, struct part b)

{

    return(a.v<b.v);

}

int f[100010];

int find1(int x)

{

    if (f[x]==x) return(x); else f[x]=find1(f[x]);

    return(f[x]);

}

bool cmp1(struct part1 a, struct part1 b)

{

    return(a.v<b.v);

}

struct part x[100010],y[100010];

struct part1 a[200010];

int n;

int main()

{

scanf("%d",&n);

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

{

    LL xx,yy;

    scanf("%lld%lld",&xx,&yy);

    x[i].v=xx;

    x[i].id=i;

    y[i].v=yy;

    y[i].id=i;

}

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

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

int o=0;

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

{

    o++;

    a[o].x=x[i].id;

    a[o].y=x[i+1].id;

    a[o].v=x[i+1].v-x[i].v;

}

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

{

    o++;

    a[o].x=y[i].id;

    a[o].y=y[i+1].id;

    a[o].v=y[i+1].v-y[i].v;

}

sort(a+1,a+1+o,cmp1);

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

    f[i]=i;

int k=0;

LL ans=0;

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

{

    int fa=find1(a[i].x);

    int fb=find1(a[i].y);

    if (fa!=fb)

    {

        f[fa]=fb;

        ans+=a[i].v;

        k++;

    }

    if (k==n-1) break;

}

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

    return(0);

}