// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5 ;

int p[N],n ;

int rnk[N];

vector < pair < int , pair < int , int > > > v;

int parent(int x){

   if(p[x] == x)

       return x;

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

}

bool isConnected(int x , int y){

   return parent(x) == parent(y);

}

void connect(int x , int y){

   if(isConnected(x,y))

       return;

   int pOfx = parent(x);

   int pOfy = parent(y);

   if(rnk[pOfx] > rnk[pOfy]){

       p[pOfy] = pOfx;

   }else if(rnk[pOfy] > rnk[pOfx]){

       p[pOfx] = pOfy;

   }else{

       p[pOfy] = pOfx;

       rnk[pOfx]++;

   }

}

void preDSU(){

   for(int i = 0;i<N;i++){

       p[i] = i;

   }

}



int main(){

    preDSU();

    scanf("%d",&n);

    vector < pair < int ,int > > v1, v2;

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

        int x,  y;

        scanf("%d%d",&x,&y);

        v1.push_back({x,i});

        v2.push_back({y,i});

    }

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

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

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

        v.push_back({v1[i].first - v1[i - 1].first,{v1[i].second,v1[i - 1].second}});

        v.push_back({v2[i].first - v2[i - 1].first,{v2[i].second,v2[i - 1].second}});

    }

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

    long long ans = 0 ;

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

        int x = v[i].second.first;

        int y = v[i].second.second;

        long long cost = v[i].first;

        if (isConnected(x, y))

            continue;

        connect(x,y);

        ans += cost;

    }

    cout << ans;

    return 0;

}


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

using namespace std;



const int mx=1e6+5;



typedef long long ll;

typedef pair<ll,ll> ii;

typedef pair<ii,ll> iii;



int par[mx], rnk[mx];



void init(int n) {

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

		par[i]=i, rnk[i]=0;

}



int find(int x) {

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

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

}



void unite(int x, int y) {

	x=find(x);

	y=find(y);

	if(x==y) return;

	if(rnk[x]<rnk[y]) par[x]=y;

	else {

		par[y]=x;

		if(rnk[x]==rnk[y]) rnk[x]++;

	}

}



bool same(int x, int y) {

	return find(x)==find(y);

}



int main() {

	cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(0);

	int N; cin>>N;

	vector<iii> v(N);

	for (int i=0; i<N; i++) {

		int x,y; cin>>x>>y;

		v[i]={{x,y},i+1};

	}

	vector<iii> edges;

	sort(v.begin(),v.end(),[&](const iii &a, const iii &b) {

		return a.first.first<b.first.first;

	});

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

		int x=v[i].second, y=v[i-1].second, w=v[i].first.first-v[i-1].first.first;

		edges.push_back({{x,y},w});

	}

	sort(v.begin(),v.end(),[&](const iii &a, const iii &b) {

		return a.first.second<b.first.second;

	});

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

		int x=v[i].second, y=v[i-1].second, w=v[i].first.second-v[i-1].first.second;

		edges.push_back({{x,y},w});

	}

	sort(edges.begin(),edges.end(),[&](const iii &a, const iii &b) {

		return a.second<b.second;

	});

	init(N+1);

	ll ret=0;

	for (auto e : edges) {

		int x=e.first.first, y=e.first.second, w=e.second;

		if(same(x,y)) continue;

		unite(x,y);

		ret+=w;

	}

	cout<<ret<<"\n";

	return 0;

}