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

    _____

  .'|||||'.

 /  >   <  \

|     ^     |

|  \     /  |

 \  '---'  /

  '._____.'

    |||||

*/



#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);

}