/*Remember: The Struggle is Important*/

//CF,CC,AtC,SPOJ: hp1999
//HE: hemant269
//HR: hemant2132

#include<bits/stdc++.h>
using namespace std;

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define T int
#define ordered_set tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>

//less_equal<T> for multiset
//order_of_key()  (value)
//find_by_order() (0-based indexing)
//insert()

//#define     int          long long int
#define     ld           long double
#define     fast()       ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define     all(x)       x.begin(),x.end()
#define     mem(a,b)     memset(a,b,sizeof(a))
#define     gcd(a,b)     (__gcd((a),(b)))
#define     lcm(a,b)     (((a)*(b))/gcd((a),(b)))
#define     pb           push_back
#define     ins          insert
#define     pii          pair<int,int>
#define     F            first
#define     S            second
#define     show(x)      for(auto c:x)cout<<c<<" ";cout<<"\n";
#define     show2(x)     for(auto c:x)cout<<c.F<<" "<<c.S<<"\n";

//const int inf=1e18,M=1e9+7;
const int N=1e5+10;

ordered_set osx,osy;
map<pii,int> mpp;
map<int,int> mpx,mpy;
vector<pii> v;
vector<pair<int,pii>> edges;

vector<int> arr(N),siz(N);

void init(int n)
{
	int i;
	for(i=1;i<=n;++i)
		arr[i]=i,siz[i]=1;
}

int root(int x)
{
	while(arr[x]!=x)
	{
		arr[x]=arr[arr[x]];   //path compression
		x=arr[x];
	}
	return x;
}

int uni(int a,int b)  //"weighted" union
{
	int ra=root(a);
	int rb=root(b);

	if(ra==rb)
        return 0;

	if(siz[ra]>siz[rb])
	{
		arr[rb]=ra;
		siz[ra]+=siz[rb];
	}
	else
	{
		arr[ra]=rb;
		siz[rb]+=siz[ra];
	}

	return 1;
}

int kruskal()
{
    int w,a,b;
    long long int res=0;
    for(auto c:edges)
    {
        w=c.F;
        a=c.S.F,b=c.S.S;

        if(uni(a,b))
            res+=w;
    }

    return res;
}

void solve()
{
    int n;
    cin>>n;

    int x,y;
    for(int i=0;i<n;++i)
    {
        cin>>x>>y;

        if(mpp.find({x,y})==mpp.end())
        {
            mpp[{x,y}];
            v.pb({x,y});

            osx.ins(x);
            osy.ins(y);

            mpx[x]=y;
            mpy[y]=x;
        }
    }

    n=v.size();

    init(n);

    for(int i=0;i<n;++i)
        mpp[{v[i].F,v[i].S}]=i+1;

    int pos,tmp;
    for(int i=0;i<n;++i)
    {
        x=v[i].F,y=v[i].S;


        pos=osx.order_of_key(x);

        if(pos+1<n)
        {
            tmp=*osx.find_by_order(pos+1);
            edges.pb({abs(x-tmp),{i+1,mpp[{tmp,mpx[tmp]}]}});
        }

        if(pos-1>=0)
        {
            tmp=*osx.find_by_order(pos-1);
            edges.pb({abs(x-tmp),{i+1,mpp[{tmp,mpx[tmp]}]}});
        }


        pos=osy.order_of_key(y);

        if(pos+1<n)
        {
            tmp=*osy.find_by_order(pos+1);
            edges.pb({abs(y-tmp),{i+1,mpp[{mpy[tmp],tmp}]}});
        }

        if(pos-1>=0)
        {
            tmp=*osy.find_by_order(pos-1);
            edges.pb({abs(y-tmp),{i+1,mpp[{mpy[tmp],tmp}]}});
        }

        /*cout<<i<<":\n";
        for(auto c:edges)
            cout<<c.F<<" "<<c.S.F<<" "<<c.S.S<<"\n";
        cout<<"....\n";
        */
    }

    //cout<<edges.size()<<"\n";
    sort(all(edges));

    long long int ans=kruskal();
    cout<<ans;
}

int32_t main()
{
    fast();

    int t=1;
    //cin>>t;
    while(t--)
    {
        solve();
        //cout<<"\n";
    }

    return 0;
}



Measured memory_bytes: 35692