// Original C++ solution (slower):
#include <bits/stdc++.h>



using namespace std;



typedef long long ll;

typedef long double ld;

typedef vector<int> vi;

typedef vector<vector<int> > vvi;

typedef pair<int, int> pii;



#define erep(i, x, n) for (auto i = x; i<=(ll)(n); i++)

#define rep(i, x, n) for(auto i = x; i<(ll)(n); i++)

#define all(v) ((v).begin()), ((v).end())

#define sz(v) ((int)((v).size()))

#define mod(n, m) (((n%m) + m)%m)

#define reset(n, m) memset(n, m, sizeof n)

#define endl '\n'



const int N = 1e5 + 5;



vector<pair<ll, int>> node[N];

map<pii, int> idx;

set<pair<ll, int>> st;

vector<pii> vec;



int n, curr = 1;

bool visited[N];



void explore(int v)

{

	visited[v] = true;

	for (auto i : node[v])

		if (!visited[i.second])

			st.insert(

			{ i.first, i.second });

}



int main()

{

	ios_base::sync_with_stdio(0);

	cin.tie(0);



	cin >> n;

	vec.resize(n);

	rep(i, 0, n)

	{

		int a, b;

		cin >> a >> b;



		if (!idx[

		{ a, b }])

			idx[

			{ a, b }] = curr++;

		vec[i] =

		{	a, b};

	}



	sort(all(vec));



	rep(i, 0, n-1)

	{

		int a = idx[vec[i]], b = idx[vec[i + 1]];

		int val = min(abs(vec[i].first - vec[i + 1].first),

				abs(vec[i].second - vec[i + 1].second));



		node[a].push_back(

		{ val, b });

		node[b].push_back(

		{ val, a });

	}



	rep(i, 0, n)

		swap(vec[i].first, vec[i].second);



	sort(all(vec));

	rep(i, 0, n-1)

	{

		int a = idx[

		{ vec[i].second, vec[i].first }], b = idx[

		{ vec[i + 1].second, vec[i + 1].first }];



		int val = min(abs(vec[i].first - vec[i + 1].first),

				abs(vec[i].second - vec[i + 1].second));



		node[a].push_back(

		{ val, b });

		node[b].push_back(

		{ val, a });

	}



	explore(1);



	ll mst = 0;

	// cost, idx, par if needed

	while (!st.empty())

	{

		auto i = st.begin();

		st.erase(st.begin());



		ll cost = i->first, idx = i->second;



		if (!visited[idx])

		{

			mst += cost;

			explore(idx);

		}

	}



	cout << mst << endl;



	return 0;

}


// Optimized solution to the same problem (faster):
#include <iostream>

#include <algorithm>

#include <cstdio>

#define rush() int T;cin>>T;while(T--)

#define go(a) while(cin>>a)

#define ms(a,b) memset(a,b,sizeof a)

#define E 1e-8

using namespace std;

typedef long long ll;

const int N=1e5+5;



    int n,m,t;

    int fa[N];

    int i,j,k;

struct point

{

    int x,y,id;

}p[N];

struct Edge

{

    int u,v,valu;

    bool const operator<(const Edge &b)

    const{

        return valu<b.valu;

    }

}edge[N];

int Find(int son)

{

    return son==fa[son] ? son : fa[son]=Find(fa[son]);

}

bool Union(int x,int y)

{

    x=Find(x),y=Find(y);

    if(x==y) return 1;

    else{

        fa[y]=x;

        return 0;

    }

}

bool cmpx(point &a,point &b){

    return a.x<b.x;

}

bool cmpy(point &a,point &b){

    return a.y<b.y;

}

int main()

{

    cin.tie(0);istream::sync_with_stdio(false);

    while(cin>>n){

        for(i=1;i<=n;i++) fa[i]=i;



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

            cin>>p[i].x>>p[i].y;

            p[i].id=i;

        }



        int num=0;

        sort(p+1,p+1+n,cmpx);//尽量以x之间的距离为经费建路

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

            edge[++num].u=p[i].id;

            edge[num].v=p[i+1].id;

            edge[num].valu=min(abs(p[i].x-p[i+1].x),abs(p[i].y-p[i+1].y));

        }

        sort(p+1,p+1+n,cmpy);//尽量以y之间的距离为经费建路

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

            edge[++num].u=p[i].id;

            edge[num].v=p[i+1].id;

            edge[num].valu=min(abs(p[i].x-p[i+1].x),abs(p[i].y-p[i+1].y));

        }



        stable_sort(edge+1,edge+1+num);

        int ans=0,cnt=0;

        for(i=1;i<=num;i++){

            if(0==Union(edge[i].u,edge[i].v)){//若u，v两点还未连接

                ans+=edge[i].valu;

                cnt++;

            }

            if(cnt==n-1) break;//建路数达到联通所有城市

        }

        cout<<ans<<endl;

    }

}

// Fastest known solution for this problem: