#include "bits/stdc++.h"
using namespace std;
///////////////////////////////////////////
const long long int INF = 1LL<<60;
const long long int Mod = 1000000007;
using ll = long long int; using ci = const int;
using vi = vector<int>;  using Vi = vector<long long int>;
using P = pair<int, int>;  using PLL = pair<ll, ll>;
using matrix = vector<vector<ll>>;
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define all(x) (x).begin(),(x).end()
#define rep(i,N) for(ll i = 0; i < (ll)N; i++)
#define repi(i,a,b) for(ll i = ll(a); i < ll(b); ++i)
template<class T>bool chmax(T &former, const T &b) { if (former<b) { former=b; return true; } return false; }
template<class T>bool chmin(T &former, const T &b) { if (b<former) { former=b; return true; } return false; }
template<class T>T sqar(T x){ return x*x; }//sqrt(x)は平方根;
#define Sort(v) std::sort(v.begin(), v.end(), std::greater<decltype(v[0])>()) //降順でVをソート
#define p_queue(v) priority_queue<v, vector<v>, greater<v> >
template<class T> inline void princ(T x){cout<<x<<" ";}; 
template<class T> inline void print(T x){cout<<x<<"\n";};
template<class T> inline void Yes(T condition){ if(condition) cout << "Yes" << endl; else cout << "No" << endl; }
template<class T> inline void YES(T condition){ if(condition) cout << "YES" << endl; else cout << "NO" << endl; }
///////////////////////////////////////////////////////////////////////////////////

struct edge{/*重み付き,有向*/
    int to , cost;/*toは接続先*/
    edge(ll to_ ,ll cost_ = 1){ to=to_; cost=cost_; };/*全てのcost=1 <=> 無向グラフ*/
};
bool operator<(edge e1 ,edge e2){return e1.cost < e2.cost; }
bool operator>(edge e1 ,edge e2){return e1.cost > e2.cost; }
using graph =  vector< vector<edge> >;

pair<graph,ll> prim(graph gg){//mstを求める. 0-indexed,連結を前提
    vector<bool> ck(gg.size(),false);
    ll lgt=0;//length
    graph mst(gg.size());//mst
    ll ct = 0;
    ck[0] = true; ct++;
    priority_queue< pair<edge,ll> , vector<pair<edge,ll>>, greater<pair<edge,ll>>> q;
    rep(i,gg[0].size()){
        q.push(mp(gg[0][i],0));
    }
    while(ct!=gg.size()){
        edge id = q.top().first;
        ll from = q.top().second;
        q.pop();
        if(ck[id.to])continue;
        ck[id.to] = true;
        mst[from].pb(id);
        lgt += id.cost;
        ct++;
        rep(i,gg[id.to].size()){
            q.push(mp(gg[id.to][i],id.to));
        }
    }
    //return lgt;//mst's length
    return mp(mst,lgt);
}

graph g;
ll n;
vector<PLL> x,y;

int main(){
    cin.tie(0);ios::sync_with_stdio(false);
    std::cout<<std::fixed<<std::setprecision(30);
    cin>>n;
    x.resize(n);
    y.resize(n);
    g.resize(n);
    rep(i,n){
        ll in,inp;
        cin>>in>>inp;
        x[i] = mp(in,i);
        y[i] = mp(inp,i);
    }
    sort(all(x));
    sort(all(y));
    rep(i,n-1){
        ll u = x[i].second;
        ll v = x[i+1].second;
        g[u].pb(edge(v,abs(x[i].first-x[i+1].first)));
        g[v].pb(edge(u,abs(x[i].first-x[i+1].first)));
    }
    rep(i,n-1){
        ll u = y[i].second;
        ll v = y[i+1].second;
        g[u].pb(edge(v,abs(y[i].first-y[i+1].first)));
        g[v].pb(edge(u,abs(y[i].first-y[i+1].first)));
    }
    ll ans = prim(g).second;
    print(ans);
    return 0;
}

Measured memory_bytes: 32492