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

#include <cstdio>

#include <cstring>

#include <algorithm>



using namespace std;

const int maxN=1e5+5;



int fa[maxN];



struct node

{

    int x,y,id;

}a[maxN],b[maxN];



struct edge

{

    int f,t,w;

}e[maxN*2];



bool cmp1(node x1,node x2)

{

    return x1.x<x2.x;

}



bool cmp2(node x1,node x2)

{

    return x1.y<x2.y;

}



bool cmp3(edge x1,edge x2)

{

    return x1.w<x2.w;

}



int find(int x)

{

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

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

}



int uni(int f,int t)

{

    f=find(f);t=find(t);

    if(f==t)return 0;

    fa[f]=t;return 1;

}



int main()

{

    int k,n,cnt=0,now=0;

    long long ans=0;

    memset(fa,-1,sizeof(fa));

    scanf("%d",&n);

    for(k=0;k<n;k++)

    {

        scanf("%d%d",&a[k].x,&a[k].y);

        a[k].id=k;b[k].id=k;

        b[k].x=a[k].x;

        b[k].y=a[k].y;

    }

    sort(a,a+n,cmp1);

    sort(b,b+n,cmp2);

    for(k=1;k<n;k++)

    {

        e[cnt].f=a[k-1].id;

        e[cnt].t=a[k].id;

        e[cnt].w=a[k].x-a[k-1].x;

        cnt++;

    }

    for(k=1;k<n;k++)

    {

        e[cnt].f=b[k-1].id;

        e[cnt].t=b[k].id;

        e[cnt].w=b[k].y-b[k-1].y;

        cnt++;

    }

    sort(e,e+cnt,cmp3);

    for(k=0;k<cnt;k++)

    {

        if(uni(e[k].f,e[k].t))

        {

            ans+=e[k].w;

            now++;

        }

        if(now==n-1)break;

    }

    cout<<ans;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.408489171268466x):


#include<bits/stdc++.h>

#define LL long long

#define MOD (LL)1000000007

#define pi acos(-1.0)

#define ULL unsigned long long

#define mem_1(str) memset(str,-1,sizeof(str))

#define mem0(str) memset(str,0,sizeof(str))

#define rep(i,a,n) for (int i=a;i<n;i++)

#define per(i,a,n) for (int i=n-1;i>=a;i--)

#define INF 999999999

using namespace std;

struct ee{            //存放每边的起点终点和权值 

	LL x,y;

	int id;

}num[200000];  

LL p[200000];

struct edge{            //存放每边的起点终点和权值 

	LL u,v;

	LL w;

}myedge[500000];  

bool cmp(const edge& p1,const edge& p2)    

{

	 if(p1.w<p2.w)return true;

     else return false;

}

bool cmpp(const ee& p1,const ee& p2)    

{

	 if(p1.x<p2.x)return true;

     else return false;

}

bool cmppp(const ee& p1,const ee& p2)    

{

	 if(p1.y<p2.y)return true;

     else return false;

}

LL findset(LL x)             //寻找根节点并压缩路径 

{

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

	else p[x]=findset(p[x]);

	return p[x];

}

LL kruskal(int n,int m)      //kruskal算法 

{

	LL x,y;

	LL ans=0;

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

	    p[i]=i;

	sort(myedge+1,myedge+m+1,cmp);

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

	{	

		x=findset(myedge[i].u);

		y=findset(myedge[i].v);

		if(x!=y)

		{

			ans+=myedge[i].w; 

			p[y]=x;                                  

		}

	}

	return ans;

}

int main()

{

	int n;

	LL ans; 

	scanf("%d",&n);

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

	{

		scanf("%lld%lld",&num[i].x ,&num[i].y );

		num[i].id =i;

	}

	sort(num+1,num+n+1,cmpp);

	int s=0;

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

	{

		myedge[++s].u =num[i].id ;

		myedge[s].v =num[i+1].id ;

		myedge[s].w =num[i+1].x -num[i].x ;

	}

	sort(num+1,num+n+1,cmppp);

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

	{

		myedge[++s].u =num[i].id ;

		myedge[s].v =num[i+1].id ;

		myedge[s].w =num[i+1].y -num[i].y ;

	}

	ans=kruskal(n,s);

	printf("%lld",ans);

}