#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <memory>
#include <complex>
#include <numeric>
#include <cstdio>
#include <iomanip>

#define REP(i, m, n) for (int i = int(m); i < int(n); i++)
#define RREP(i, m, n) for (int i = int(n) - 1; i >= int(m); --i)
#define EACH(i, c) for (auto &(i) : c)
#define all(c) begin(c), end(c)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(begin(c), end(c))
#define pb emplace_back
#define MP make_pair
#define SZ(a) int((a).size())

#ifdef LOCAL
#define DEBUG(s) cout << (s) << endl
#define dump(x) cerr << #x << " = " << (x) << endl
#define BR cout << endl;
#else
#define DEBUG(s) \
    do           \
    {            \
    } while (0)
#define dump(x) \
    do          \
    {           \
    } while (0)
#define BR
#endif
using namespace std;

using UI = unsigned int;
using UL = unsigned long;
using LL = long long int;
using ULL = unsigned long long;
using VI = vector<int>;
using VVI = vector<VI>;
using VLL = vector<LL>;
using VVLL = vector<VLL>;
using VS = vector<string>;
using PII = pair<int, int>;
using VP = vector<PII>;

struct edge
{
    int from, to, cost;
    edge(int from, int to, int cost) : from(from), to(to), cost(cost) {}
};

constexpr double EPS = 1e-10;
//constexpr double PI  = acos(-1.0);
//constexpr int INF = INT_MAX;
constexpr int MOD = 1'000'000'007;
//inline void modAdd(LL &l, LL &r) {l = (l + r) % MOD;}

template <class T>
inline T sqr(T x) { return x * x; }

class UnionFind
{
    struct UFNode
    {
        int par;
        int rank;
    };
    vector<UFNode> nodes;

public:
    UnionFind(int n) : nodes(n)
    {
        for (int i = 0; i < n; i++)
        {
            nodes[i].par = i;
            nodes[i].rank = 0;
        }
    };
    int root(int x)
    {
        return nodes[x].par == x ? x : root(nodes[x].par);
    }
    bool same(int x, int y)
    {
        return root(x) == root(y);
    }
    void unite(int x, int y)
    {
        x = root(x);
        y = root(y);
        if (x == y)
            return;
        if (nodes[x].rank < nodes[y].rank)
        {
            nodes[x].par = y;
        }
        else
        {
            nodes[y].par = x;
            if (nodes[x].rank == nodes[y].rank)
                nodes[x].rank++;
        }
    }
    //~UnionFind() {cout << nodes.size() << endl;}
};

struct S
{
    int x, y, i;
};

void solve()
{
    int n;
    cin >> n;
    vector<S> p(n);
    REP(i, 0, n)
    {
        cin >> p[i].x >> p[i].y;
        p[i].i = i;
    }

    UnionFind uf(n);
    vector<edge> es;

    sort(all(p), [](auto &l, auto &r) { return l.x < r.x; });
    REP(i, 0, n - 1)
    {
        int d = min(abs(p[i].x - p[i + 1].x), abs(p[i].y - p[i + 1].y));
        es.pb(p[i].i, p[i + 1].i, d);
    }
    sort(all(p), [](auto &l, auto &r) { return l.y < r.y; });
    REP(i, 0, n - 1)
    {
        int d = min(abs(p[i].x - p[i + 1].x), abs(p[i].y - p[i + 1].y));
        es.pb(p[i].i, p[i + 1].i, d);
    }

    sort(all(es), [](auto &l, auto &r) { return l.cost < r.cost; });

    LL ans = 0;
    for (auto &e : es)
    {
        int l = e.from, r = e.to, d = e.cost;
        if (uf.same(l, r))
            continue;
        uf.unite(l, r);
        ans += d;
    }
    cout << ans << endl;
}

int main()
{
    solve();

    return 0;
}

Measured memory_bytes: 6900