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

using namespace std;

int n,x,y,k;

long long ans=0;

const int inf = 0x3f3f3f3f;

#define ft first

#define se second

const int maxn=100007;

pair <int,int> r[maxn];

pair <int,int> c[maxn];

struct Node{

	int u,v,cst;

}ege[2*maxn+1000];

Node make_node(int a,int b,int c){

	Node node;

	node.u=a;

	node.v=b;

	node.cst=c;

	return node;

}

int f[maxn],rnk[maxn];

int fnd(int x){

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

	return f[x]=fnd(f[x]);

}

void merge(int x,int y){

	x=fnd(x);

	y=fnd(y);

	if (rnk[x]>rnk[y])f[y]=x;

	else {

		f[x]=y;

		if (rnk[x]==rnk[y])rnk[y]++;

	}

}

bool cmp(Node a,Node b){

	return a.cst<b.cst;

}

void K(){

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

		if (fnd(ege[i].u)==fnd(ege[i].v))continue;

		ans+=ege[i].cst;

		merge(ege[i].u,ege[i].v);

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

	}

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

}

int main(){

	scanf("%d",&n);

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

		scanf("%d%d",&x,&y);

		r[i]=make_pair(x,i);

		c[i]=make_pair(y,i);

	}

	sort(r,r+n);

	sort(c,c+n);

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

		ege[++k]=make_node(r[i-1].se,r[i].se,abs(r[i].ft-r[i-1].ft));

		ege[++k]=make_node(c[i-1].se,c[i].se,abs(c[i].ft-c[i-1].ft));

	}

	sort(ege+1,ege+1+k,cmp);

	memset(f,inf,sizeof f);

	for (int i=0;i<n;++i)f[i]=i,rnk[i]=1;

	K();

	return 0;

}

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



using namespace std;



#define fi first

#define se second

#define pb push_back

#define mp make_pair



typedef pair<long long,long long> ii;

vector<pair<long long,ii>> edge;

long long n,up[100005],sz[100005];

pair<ii,long long> x[100005];



bool cmp(const pair<ii,long long> &a,const pair<ii,long long> &b){

    return a.fi.fi<b.fi.fi;

}

bool cmp1(const pair<ii,long long> &a,const pair<ii,long long> &b){

    return a.fi.se<b.fi.se;

}

int findSet(int x){

    if(x==up[x]) return x;

    else return findSet(up[x]);

}

void unionSet(int x,int y){

    long long x1=findSet(x),y1=findSet(y);

    if(sz[x1]<sz[y1]) swap(x1,y1);

    up[y1]=x1;

    sz[x1]+=sz[y1];

}

bool checkSet(int x,int y){

    long long x1=findSet(x),x2=findSet(y);

    if(x1==x2)

        return 1;

    else

        return 0;

}

int main(){

    cin.tie(0),cout.tie(0),ios::sync_with_stdio(0);

    cin>>n;

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

        cin>>x[i].fi.fi>>x[i].fi.se;

        x[i].se=i;

    }

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

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

        up[i]=i;

        sz[i]=1;

    }

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

        long long x1=x[i].se,x2=x[i+1].se;

        long long val=abs(x[i].fi.fi-x[i+1].fi.fi),val1=abs(x[i].fi.se-x[i+1].fi.se);

        edge.pb(mp(min(val,val1),mp(x1,x2)));

    }

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

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

        long long x1=x[i].se,x2=x[i+1].se;

        long long val=abs(x[i].fi.fi-x[i+1].fi.fi),val1=abs(x[i].fi.se-x[i+1].fi.se);

        edge.pb(mp(min(val,val1),mp(x1,x2)));

    }

    long long sum=0;

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

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

        long long x1=edge[i].se.fi,x2=edge[i].se.se;

        if(checkSet(x1,x2)==0){

            unionSet(x1,x2);

            sum+=edge[i].fi;

        }

    }

    cout<<sum;

}