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

using namespace std;



#define ENGZ ios::sync_with_stdio(0);cin.tie(0);ios_base::sync_with_stdio(0);

#define sfi(x) scanf("%d" , &x)

#define sfi2(x, y) scanf("%d%d" , &x,&y)

#define sfl2(x, y) scanf("%I64d%I64d" , &x,&y)

#define sfl(x) scanf("%I64d" , &x)

#define sfl3(x, y, z) scanf("%I64d%I64d%I64d", &x, &y, &z)

#define sfd(x) scanf("%lf", &x)

#define sfd2(x, y) scanf("%lf", &x, &y)

#define sfs(x) scanf("%s", &x)

#define testv(x) cerr << x << ' '

#define wtf(s) freopen((s), "w", stdout)

#define rff(s) freopen((s), "r", stdin)

#define test cerr << "here"

#define fst(x) cout << fixed << setprecision(x)

#define mod 1000000007

#define pi (2 * acos(0))

typedef long double ld;

typedef long long ll;



int par[200005], rnk[200005];



int findp(int x)

{

    if (par[x] == x)

        return x;

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

}



bool iscon(int x, int y)

{

    if (findp(x) == findp(y))

        return true;

    return false;

}



void con(int x, int y)

{

    int px = findp(x), py = findp(y);

    if (rnk[px] > rnk[py])

        par[py] = px;

    else if (rnk[px] < rnk[py])

        par[px] = py;

    else

        par[px] = py, rnk[px]++;

}





    pair<pair<ll, ll>, int> a[100005], b[100005];

int main()

{

    ENGZ

    int n;

    ll ans = 0;

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

        par[i] = i;

    cin >> n;

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

    {

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

        b[i].first.first = a[i].first.second;

        b[i].first.second = a[i].first.first;

        a[i].second = b[i].second = i;

    }

    sort(a, a + n);

    sort(b, b + n);

    map<ll, vector<pair<int, int>>> mp;

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

    {

        mp[abs(a[i].first.first - a[i + 1].first.first)].push_back({a[i].second, a[i + 1].second});

        mp[abs(b[i].first.first - b[i + 1].first.first)].push_back({b[i].second, b[i + 1].second});

    }

    for (auto it: mp)

    {

        for (auto i: it.second)

        {

            if (!iscon(i.first, i.second))

                con(i.first, i.second), ans += it.first;

        }

    }

    cout << ans;

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.404668110982827x):
// #define FNAME "template"



#define NDEBUG



#include <bits/stdc++.h>

using namespace std;



typedef long long inte;

const int maxn = 100005;



#ifndef NDEBUG

#    define dprint(x) (cerr << (#x) << " = "<< (x) << endl)

#else

#    define dprint(x) (NULL)

#endif



template<typename T>

inline void readFig(T& x)

{

#   ifdef FTREAD

        static int c = 0;

        int op = 1;

        x = 0;

        while (!isdigit(c)) {

            if (c == '-')

                op = -1;

            c = getchar();

        }

        while (isdigit(c)) {

            x *= 10;

            x += c - '0';

            c = getchar();

        }

        x *= op;

#   else

        cin >> x;

#   endif

}



int N, M;

struct Edge {

    int u, v, w;

} edges[maxn * 2];

inline bool operator < (const Edge &a, const Edge &b)

{

    return a.w < b.w;

}



int par[maxn];

int getPar(int x)

{

    static int st[maxn];

    int stop = 0;

    while (par[x] != x) {

        x = par[x];

        st[stop++] = x;

    }

    while (stop--)

        par[st[stop]] = x;

    return x;

}

inline inte genMST()

{

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

        par[i] = i;

    int cnt = 0;

    inte ans = 0;

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

        int u = getPar(edges[i].u), v = getPar(edges[i].v);

        if (u != v) {

            par[u] = v;

            ++cnt;

            ans += edges[i].w;

            dprint(ans);

        }

    }

    //assert(cnt == N - 1);

    return ans;

}



struct City {

    int x, y, id;

} cities[maxn];



inline bool compx(const City &a, const City &b)

{

    return a.x < b.x;

}

inline bool compy(const City &a, const City &b)

{

    return a.y < b.y;

}

inline int getdis(const City &a, const City &b)

{

    return min(abs(a.x - b.x), abs(a.y - b.y));

}



inline void solve()

{

    readFig(N);

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

        readFig(cities[i].x); readFig(cities[i].y);

        cities[i].id = i;

    }

    sort(cities + 1, cities + N + 1, compx);

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

        edges[++M].u = cities[i].id;

        edges[M].v = cities[i + 1].id;

        edges[M].w = getdis(cities[i], cities[i + 1]);

    }

    sort(cities + 1, cities + N + 1, compy);

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

        edges[++M].u = cities[i].id;

        edges[M].v = cities[i + 1].id;

        edges[M].w = getdis(cities[i], cities[i + 1]);

    }

    sort(edges + 1, edges + M + 1);

    cout << genMST() << endl;

}



signed main()

{

#   ifdef FNAME

        freopen(FNAME".in", "r", stdin);

        freopen(FNAME".out", "w", stdout);

#   endif

#   ifndef FTREAD

    	ios::sync_with_stdio(false);

    	cin.tie(0);

#   endif



#   ifdef MULTEST

        int T;

        readFig(T);

        while (T--)

            solve();

#   else

        solve();

#   endif



#   ifdef FNAME

        fclose(stdin);

        fclose(stdout);

#   endif

    	return 0;

}