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

using namespace std;

typedef long long ll;

const int maxn=1e6+10;

const int MAXM=1e6+10;

int F[maxn];

struct node

{

    int x,y,id;

}sp[maxn];

bool cmp2(node a,node b)

{

    return a.x<b.x;

}

bool cmp3(node a,node b)

{

    return a.y<b.y;

}

struct Edge

{

    int u,v,w;

}e[MAXM];

int tol;

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

{

    e[tol].u=u;

    e[tol].v=v;

    e[tol++].w=w;

}

bool cmp(Edge a,Edge b)

{

    return a.w<b.w;

}

int Find(int x)

{

    if(F[x]==-1)return x;

    else return F[x]=Find(F[x]);

}

int Krustal(int n)

{

    memset(F,-1,sizeof(F));

    sort(e,e+tol,cmp);

    int cnt=0;

    int ans=0;

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

    {

        int u=e[i].u;

        int v=e[i].v;

        int w=e[i].w;

        int t1=Find(u);

        int t2=Find(v);

       // cout<<t1<<' '<<t2<<endl;

        if(t1!=t2)

        {

            ans+=w;

            F[t1]=t2;

            cnt++;

        }

        if(cnt==n-1) break;

    }

   // cout<<cnt<<endl;

    if(cnt<n-1)return -1;

    else return ans;

}

int main()

{

    int n;

    cin>>n;

    tol=0;

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

    {

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

        sp[i].id=i;

    }

    sort(sp+1,sp+1+n,cmp2);

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

    {

        addedge(sp[i].id,sp[i+1].id,sp[i+1].x-sp[i].x);

    }

    sort(sp+1,sp+1+n,cmp3);

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

    {

        addedge(sp[i].id,sp[i+1].id,sp[i+1].y-sp[i].y);

    }

    int ans=Krustal(n);

    cout<<ans<<endl;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 5.019430054670724x):
#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;

}