// Slower C++ solution:
#include<iostream>

#include<fstream>

#include<sstream>

#include<algorithm>

#include<cstdio>

#include<cassert>

#include<cmath>

#include<cstdlib>

#include<cstring>

#include<string>

#include<deque>

#include<queue>

#include<vector>

#include<list>

#include<map>

#include<set>

#include<bitset>

#include<stack>

#include<iomanip>

#include<utility>

#include<functional>

using namespace std;

int n,m;

int ans;

int par[100005];

vector<int> edge[100005];

vector<pair<int,int> > el;

pair<int,int> e[200005];

pair<pair<int,int>,int> a[100005],b[100005];

int find(int x)

{

	if(par[x]!=x)

		return par[x]=find(par[x]);

	else

		return par[x];

}

bool unite(int x,int y)

{

	x=find(x);

	y=find(y);

	if(x==y)

		return false;

	else

	{

		par[x]=y;

		return true;

	}

}

int main()

{

	cin>>n;

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

	{

		cin>>a[i].first.first>>a[i].first.second;

		b[i].first.first=a[i].first.second;

		b[i].first.second=a[i].first.first;

		a[i].second=b[i].second=i;

	}

	sort(a,a+n);

	sort(b,b+n);

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

	{

		edge[a[i].second].push_back(a[i-1].second);

		e[m]=make_pair(a[i].second,a[i-1].second);

		el.push_back(make_pair(a[i].first.first-a[i-1].first.first,m++));

	}

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

	{

		edge[b[i].second].push_back(b[i-1].second);

		e[m]=make_pair(b[i].second,b[i-1].second);

		el.push_back(make_pair(b[i].first.first-b[i-1].first.first,m++));

	}

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

		par[i]=i;

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

	for(int i=0;i<m;i++)

	{

		int xx=e[el[i].second].first;

		int yy=e[el[i].second].second;

		if(unite(xx,yy))

			ans+=el[i].first;

	}

	cout<<ans;

	return 0;

}


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

#define lowbit(i) ((i)&(-i))

#define lson(i) ((i)<<1)

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

#define ft first

#define se second

#define MAXN 100007

using namespace std;



typedef long long ll;typedef unsigned long long ul;

typedef pair<int,int> pii;typedef pair<ll,ll> pll;

typedef vector<string> vss;

typedef vector<int> vii;typedef vector<pii> vpi;

typedef queue<int> qii;typedef queue<pii> qpi;



const int inf=2e9+7;



struct edge{

	ll x,y,val;

	edge(int _x,int _y,int _val){x=_x,y=_y,val=_val;}

};



vector<edge> v;



struct node{

	int x,y,num;

}dot1[MAXN],dot2[MAXN];



bool cmp1(node x,node y){

	return x.x<y.x;

}



bool cmp2(node x,node y){

	return x.y<y.y;

}



bool comp(edge x,edge y){

	return x.val<y.val;

}



int n,fa[MAXN];

ll res;



int find(int x){

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

	return fa[x]=find(fa[x]);

}



void merge(int x,int y){

	int fx=find(x),fy=find(y);

	if(fx!=fy)

		fa[fx]=fy;

}



int main()

{

// 	freopen("","r",stdin);

// 	freopen("","w",stdout);

	scanf("%d",&n);

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

		scanf("%d%d",&dot1[i].x,&dot1[i].y);

		dot2[i].x=dot1[i].x;dot2[i].y=dot1[i].y;

		dot2[i].num=dot1[i].num=i;

	}

	

	//建边(删除无用边) 

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

	sort(dot2+1,dot2+n+1,cmp2);

	/*

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

		printf("num %d:(%d,%d)\n",i,dot1[i].x,dot1[i].y);

	}

	*/

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

		v.push_back( edge(dot1[i-1].num,dot1[i].num,dot1[i].x-dot1[i-1].x) );

		v.push_back( edge(dot2[i-1].num,dot2[i].num,dot2[i].y-dot2[i-1].y) );

	}

	sort(v.begin(),v.end(),comp);

	

	//初始化 

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

		fa[i]=i;

    /*

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

		printf("(%d,%d) dis=%d\n",v[i].x,v[i].y,v[i].val);

	}

	*/

	//Kruscal

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

		if(find(v[i].x)!=find(v[i].y)){

			merge(v[i].x,v[i].y);

			res+=v[i].val;

		}

	}

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

	return 0;

}