// 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.368108680839154x):
#include<bits/stdc++.h>

using namespace std;



#define int long long

#define pb push_back

#define fi first

#define se second



const int N=1e5+5;

typedef pair<int,int> ii;

typedef pair<int,ii> iii;



int n,ans;

int pset[N],s[N];

vector<ii> vx,vy;

map<ii,int> ma;

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



bool how_sort(ii a,ii b){

    if(a.se!=b.se)

            return a.se<b.se;

    return a.fi<b.fi;

}



int unionfind(int u){

    return (u==pset[u]) ? u : (pset[u]=unionfind(pset[u]));

}

bool compare(int u,int v){

    return (unionfind(u)==unionfind(v)) ? true :false;

}

void unionset(int i,int j)

{

    int x=unionfind(i),y=unionfind(j);

    if(s[x]>s[y]){

        pset[y]=x;

        s[x]+=s[y];

    }

    else{

        pset[x]=y;

        s[y]+=s[x];

    }

}

signed main(){

	ios_base::sync_with_stdio(false);

	cin.tie(0);

	int cnt=0;

    cin>>n;

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

        int a,b;

        cin>>a>>b;

        if(ma[ii(a,b)])continue;

        ma[ii(a,b)]=++cnt;

        vx.pb(ii(a,b));

        vy.pb(ii(a,b));

        pset[cnt]=cnt;

        s[cnt]=1;

    }

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

    sort(vy.begin(),vy.end(),how_sort);

    

	

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

        int a=vx[i].fi-vx[i-1].fi;

        pq.push(iii(a,ii(ma[vx[i]],ma[vx[i-1]])));

	

        int b=vy[i].se-vy[i-1].se;

        pq.push(iii(b,ii(ma[vy[i]],ma[vy[i-1]])));

    }

    while(!pq.empty()){

        iii x=pq.top();

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

        pq.pop();

        if(!compare(u,v)){

            unionset(u,v);

            ans+=w;

        }

    }

    cout<<ans;

}