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

using namespace std;



const int N = 1e5 + 7;



int fa[N];

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

vector<pair<int, pair<int, int> > > e;



void init()

{

    v.clear();

    e.clear();

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

        fa[i] = i;

}



void addEdge(int u, int v, int w)

{

    e.push_back(make_pair(w, make_pair(u, v)));

}



int find(int x)

{

    if(fa[x] != x)

        fa[x] = find(fa[x]);

    return fa[x];

}



void merge(int a, int b)

{

    a = find(a);

    b = find(b);

    if(fa[a] != fa[b])

        fa[a] = fa[b];

}



int main()

{

    int n;

    while(cin >> n)

    {

        init();

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

        {

            int x, y;

            cin >> x >> y;

            v.push_back(make_pair(i, make_pair(x, y)));

        }

        sort(v.begin(), v.end(), [](pair<int, pair<int, int>> a, pair<int, pair<int, int>> b) {

            return a.second < b.second;

        });

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

        {

            auto p1 = v[i - 1].second;

            auto p2 = v[i].second;

            addEdge(v[i].first, v[i - 1].first, min(abs(p1.first - p2.first), abs(p1.second - p2.second)));

        }

        sort(v.begin(), v.end(), [](pair<int, pair<int, int>> a, pair<int, pair<int, int>> b) {

            return a.second.second < b.second.second || (a.second.second == b.second.second && a.second.first < b.second.first);

        });

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

        {

            auto p1 = v[i - 1].second;

            auto p2 = v[i].second;

            addEdge(v[i].first, v[i - 1].first, min(abs(p1.first - p2.first), abs(p1.second - p2.second)));

        }

        long long sum = 0;

        sort(e.begin(), e.end(), [](pair<int, pair<int, int>> a, pair<int, pair<int, int>> b) {

            return a.first < b.first;

        });

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

        {

            int u = e[i].second.first;

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

            int w = e[i].first;

            if(find(u) == find(v))

                continue;

            sum += w;

            merge(u, v);

        }

        cout << sum << endl;

    }

}

// Optimized solution to the same problem (faster):
#define _USE_MATH_DEFINES

#include <algorithm>

#include <array>

#include <bitset>

#include <cassert>

#include <cctype>

#include <climits>

#include <clocale>

#include <cmath>

#include <cstdio>

#include <cstdlib>

#include <ctime>

#include <deque>

#include <fstream>

#include <functional>

#include <iomanip>

#include <iostream>

#include <iterator>

#include <list>

#include <map>

#include <numeric>

#include <queue>

#include <regex>

#include <set>

#include <sstream>

#include <stack>

#include <string>

#include <tuple>

#include <unordered_map>

#include <unordered_set>

#include <utility>

#include <vector>



using namespace std;



#define IOS ios::sync_with_stdio(false); cin.tie(0);

#define FOR(i, s, n) for(int i = (s), i##_len=(n); i < i##_len; ++i)

#define FORS(i, s, n) for(int i = (s), i##_len=(n); i <= i##_len; ++i)

#define VFOR(i, s, n) for(int i = (s); i < (n); ++i)

#define VFORS(i, s, n) for(int i = (s); i <= (n); ++i)

#define REP(i, n) FOR(i, 0, n)

#define REPS(i, n) FORS(i, 0, n)

#define VREP(i, n) VFOR(i, 0, n)

#define VREPS(i, n) VFORS(i, 0, n)

#define RFOR(i, s, n) for(int i = (s), i##_len=(n); i >= i##_len; --i)

#define RFORS(i, s, n) for(int i = (s), i##_len=(n); i > i##_len; --i)

#define RREP(i, n) RFOR(i, n, 0)

#define RREPS(i, n) RFORS(i, n, 0)

#define LLFOR(i, s, n) for(ll i = (s), i##_len=(n); i < i##_len; ++i)

#define LLFORS(i, s, n) for(ll i = (s), i##_len=(n); i <= i##_len; ++i)

#define LLVFOR(i, s, n) for(ll i = (s); i < (n); ++i)

#define LLVFORS(i, s, n) for(ll i = (s); i <= (n); ++i)

#define LLREP(i, n) LLFOR(i, 0, n)

#define LLREPS(i, n) LLFORS(i, 0, n)

#define LLVREP(i, n) LLVFOR(i, 0, n)

#define LLVREPS(i, n) LLVFORS(i, 0, n)

#define LLRFOR(i, s, n) for(ll i = (s). i##_len=(n); i >= i##_len; --i)

#define LLRFORS(i, s, n) for(ll i = (s), i##_len=(n); i > i##_len; --i)

#define LLRREP(i, n) LLRFOR(i, n, 0)

#define LLRREPS(i, n) LLRFORS(i, n, 0)

#define IREP(i, v) for(auto i = (v).begin(); i != (v).end(); ++i)

#define IRREP(i, v) for(auto i = (v).rbegin(); i != (v).rend(); ++i)

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

#define RALL(v) (v).rbegin(), (v).rend()

#define SORT(v) sort(ALL(v))

#define RSORT(v) sort(RALL(v))

#define SZ(x) ((int)(x).size())

#define REV(x) reverse(ALL(x))

#define PB push_back

#define EB emplace_back

#define MP make_pair

#define MT make_tuple

#define BIT(n) (1LL<<(n))

#define UNIQUE(v) v.erase(unique(ALL(v)), v.end())



using ld = long double;

using ll = long long;

using ui = unsigned int;

using ull = unsigned long long;

using Pi_i = pair<int, int>;

using Pll_ll = pair<ll, ll>;

using VB = vector<bool>;

using VC = vector<char>;

using VD = vector<double>;

using VI = vector<int>;

using VLL = vector<ll>;

using VS = vector<string>;

using VSH = vector<short>;

using VULL = vector<ull>;



const int MOD = 1000000007; 

const int INF = 1000000000; //1e9

const int NIL = -1;

const ll LINF = 1000000000000000000; // 1e18

const double EPS = 1E-10;



template<class T, class S>

bool chmax(T &a, const S &b){

    if(a < b){

        a = b; return true;

    }

    return false;

}

template<class T, class S>

bool chmin(T &a, const S &b){

    if(b < a){

        a = b; return true;

    }

    return false;

}







struct edge{

    int from, to, cost;

    edge(int From, int To, int Cost): from(From), to(To), cost(Cost){};

};



int V; //頂点数

vector<edge> G;



bool edgeComp(const edge& e1, const edge& e2){

    return e1.cost < e2.cost;

}



class UnionFind{

    vector<int> par;

    vector<int> rank;



public:

    UnionFind(){}

    UnionFind(int n): par(n), rank(n){

        REP(i, n){

            par[i] = i;

            rank[i] = 0;

        }

    }



    void resize(int n){

        int m = par.size();

        par.resize(n);

        rank.resize(n, 0);

        FOR(i, m, n) par[i] = i;

    }



    int find(int x){

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

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

    }



    void unit(int x, int y){

        x = find(x);

        y = find(y);

        if(x == y) return;



        if(rank[x] < rank[y]){

            par[x] = y;

        }else{

            par[y] = x;

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

        }

    }



    bool same(int x, int y){

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

    }

};



int kruskal(){

    sort(ALL(G), edgeComp);

    int res = 0;

    UnionFind UF(V);

    for(edge &e: G){

        if(!UF.same(e.from, e.to)){

            UF.unit(e.from, e.to);

            res += e.cost;

        }

    }

    return res;

}



int main(){

    cin >> V;

    //x,y,idx と y,x,id

    vector<pair<Pi_i, int>> px(V), py(V);

    REP(i, V){

        px[i].second = py[i].second = i;

        cin >> px[i].first.first >> px[i].first.second;

        py[i].first.first = px[i].first.second;

        py[i].first.second = px[i].first.first;

    }

    SORT(px); SORT(py);

    REP(i, V-1){

        G.push_back({px[i].second, px[i+1].second, 

                    abs(px[i].first.first - px[i+1].first.first)});

        G.push_back({py[i].second, py[i+1].second, 

                    abs(py[i].first.first - py[i+1].first.first)});

    }

    cout << kruskal() << endl;

    return 0;

}


// Fastest known solution for this problem: