#include <bits/stdc++.h>
#define rep(n) for(int I = 0; (I) < (n); ++(I) )
#define repeat(i, n) for( int i = 0; (i) < (n); ++(i) )
#define repeat_to(i, n) for( int i = 0; (i) <= (n); ++(i) )
#define repeat_from(i, m, n) for( int i = (m); (i) < (n); ++(i) )
#define repeat_from_to(i, m, n) for( int i = (m); (i) <= (n); ++(i) )
#define el cout << endl
#define dump(x) cout << " " << #x << "=" << x
#define vdump(v) for(size_t T=0; T<v.size(); ++T){cout << " " << #v << "[" << T << "]=" << v[T];} cout << endl
using namespace std;
using lint = long long;
using ld = long double;

// ユニオンファインドツリー
struct uf_tree {
    vector<int> parent;
    int internal_size;
    uf_tree(int size_) : parent(size_, -1), internal_size(size_) {}
    void unite(int x, int y) {
        if ((x = find(x)) != (y = find(y))) {
            if (parent[y] < parent[x]) swap(x, y);
            parent[x] += parent[y];
            parent[y] = x;
            internal_size--;
        }
    }
    bool is_same(int x, int y) { return find(x) == find(y); }
    int find(int x) { return parent[x] < 0 ? x : parent[x] = find(parent[x]); }
    int size(int x) { return -parent[find(x)]; }
    int size() { return internal_size; }
};

/****************** グラフ ******************/
// 諸宣言
using Weight = lint;
using Flow = lint;
struct Edge {
    int src, dst;
    Weight weight;
    Flow cap;
    Edge() : src(0), dst(0), weight(0) {}
    Edge(int s, int d, Weight w) : src(s), dst(d), weight(w) {}
    Edge(int s, int d, Weight w, Flow c) : src(s), dst(d), weight(w), cap(c) {}
};
using Edges = vector<Edge>;
using Graph = vector<Edges>;
using Array = vector<Weight>;
using Matrix = vector<Array>;

void add_edge(Graph &g, int a, int b, Weight w = 1, Flow c = 1) {
    g[a].emplace_back(a, b, w, c);
    g[b].emplace_back(b, a, w, c);
}
void add_arc(Graph &g, int a, int b, Weight w = 1, Flow c = 1) {
    g[a].emplace_back(a, b, w, c);
}

// クラスカル法（「ユニオンファインドツリー」が必要） O(Eα(E))
pair<Weight, Edges> kruskal(Graph const &g) {
    uf_tree uf(g.size());
    Edges es;
    for (auto &adj : g)
        for (auto &e : adj)
            es.emplace_back(e);
    sort(es.begin(), es.end(),
        [](const Edge &e, const Edge &f) { return e.weight < f.weight; });
    Weight total = 0;
    Edges T;
    for (auto &e : es)
        if (!uf.is_same(e.src, e.dst)) {
            T.push_back(e);
            total += e.weight;
            uf.unite(e.src, e.dst);
        }
    return make_pair(total, T);
}

int main(void) {
    int n;
    cin >> n;
    struct P {int idx; int x; int y;};
    vector<P> v(n);
    repeat(i, n) {
        v[i].idx = i;
        cin >> v[i].x >> v[i].y;
    }
    
    Graph g(n);
    
    sort(v.begin(), v.end(), 
         [](const P &a, const P &b) {
             if (a.x != b.x) return a.x < b.x;
             else return a.y < b.y;
         });
    
    repeat(i, n-1) {
        add_edge(g, v[i].idx, v[i+1].idx, v[i+1].x-v[i].x);
    }
    
    sort(v.begin(), v.end(),
         [](const P &a, const P &b) {
             if (a.y != b.y) return a.y < b.y;
             else return a.x < b.x;
         });
    
    repeat(i, n-1) {
        add_edge(g, v[i].idx, v[i+1].idx, v[i+1].y-v[i].y);
    }
    
    auto ans = kruskal(g);
    cout << ans.first << endl;
    return 0;
}   

Measured memory_bytes: 33644