// https://atcoder.jp/contests/abc065/tasks/arc076_b

#include <iostream>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
#include <numeric>
#include <array>
#include <queue>
using namespace std;

#define REP(i,n) for(int i=0, i##_len=(n); i<i##_len; ++i)
#define pow(x) x*x
#define ll long long
static const int MAX = 100010;
static const ll INFTY = 1e18;

struct pos {
    ll x;
    ll y;
};
struct edge {
    ll to;
    ll cost;
};
using Graph = vector<vector<edge>>;
// <最短距離, 頂点の番号>
using P = pair<ll, ll>;

int seen[MAX];


//対象の頂点からのびる辺を調べていって，一番小さいものを全域木に追加する．
//もう訪れていた場合は追加しない．
ll prim(const Graph &G, ll N, ll s) {
    priority_queue<P, vector<P>, greater<P> > que;
    fill(seen, seen+N, 0);
    que.push(P(0, s));
    ll total = 0;

    while (!que.empty()) {
        P p = que.top();
        que.pop();
        ll v = p.second;
        if( seen[v] == 1 ) continue;
        total += p.first;
        seen[v] = 1;
        for (ll i=0; i<G[v].size(); ++i) {
            edge e = G[v][i];
            que.push(P(e.cost, e.to));
        }
    }

    return total;
}



int main() {

    ll N; cin >> N;
    vector<pair<pos, ll>> city(N);
    vector<pair<pos, ll>> ans_city(N);
    vector<pair<ll, ll>> x_city(N);
    vector<pair<ll, ll>> y_city(N);    
    Graph G(N);

    REP(i, N){
        ll x,y;
        cin >> x >> y;
        city[i].first.x = x; city[i].first.y = y; city[i].second = i; 
        x_city[i].first = x; x_city[i].second = i; 
        y_city[i].first = y; y_city[i].second = i;
    }
    sort(x_city.begin(), x_city.end());
    REP(i, N){
        ans_city[i].first.x = city[x_city[i].second].first.x; 
        ans_city[i].first.y = city[x_city[i].second].first.y; 
        ans_city[i].second = city[x_city[i].second].second; 
    }
    REP(i, N-1){
        ll cost = min( abs( ans_city[i].first.x - ans_city[i+1].first.x ), abs( ans_city[i].first.y - ans_city[i+1].first.y  ));
        edge e = { ans_city[i+1].second, cost };
        G[ans_city[i].second].push_back(e);
        e = { ans_city[i].second, cost };
        G[ans_city[i+1].second].push_back(e);
    }
    sort(y_city.begin(), y_city.end());
    REP(i, N){
        ans_city[i].first.x = city[y_city[i].second].first.x; 
        ans_city[i].first.y = city[y_city[i].second].first.y; 
        ans_city[i].second = city[y_city[i].second].second;  
    }
    REP(i, N-1){
        ll cost = min( abs( ans_city[i].first.x - ans_city[i+1].first.x ), abs( ans_city[i].first.y - ans_city[i+1].first.y  ));
        edge e = { ans_city[i+1].second, cost };
        G[ans_city[i].second].push_back(e);
        e = { ans_city[i].second, cost };
        G[ans_city[i+1].second].push_back(e);
    }
    ll ans = prim(G, N, 0);

    cout << ans << endl;

    
}
/*
                   _ooOoo_
                  o8888888o
                  88" . "88
                  (| -_- |)
                  O\  =  /O
               ____/`---'\____
             .'  \\|     |//  `.
            /  \\|||  :  |||//  \
           /  _||||| -:- |||||-  \
           |   | \\\  -  /// |   |
           | \_|  ''\---/''  |   |
           \  .-\__  `-`  ___/-. /
         ___`. .'  /--.--\  `. . __
      ."" '<  `.___\_<|>_/___.'  >'"".
     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
     \  \ `-.   \_ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-'======
                   `=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         pass System Test!
*/

Measured memory_bytes: 25968