#include <iostream>
#include <iomanip>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <array>
#include <tuple>
#include <string>
#include <algorithm>
#include <functional> // greater など
#include <cmath>      // abs など
#include <numeric>    // accumulate, gcd など
#include <cassert>    // assert
#include <stdexcept>
#include <bitset>
using namespace std;

// #include <boost/multiprecision/cpp_int.hpp>
// using namespace boost::multiprecision;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
typedef long long ll;
// typedef int128_t ll;
// typedef cpp_int ll;

// GCC, 配列のアクセスなど
#define _GLIBCXX_DEBUG
// Clang, 配列のアクセスなど
#define _LIBCPP_DEBUG 0

// #define NDEBUG 1
// debug用出力 https://trap.jp/post/998/
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T)
{
    cerr << H << " ";
    debug_out(T...);
}
#ifdef NDEBUG
#define debug(...)
#else
#define debug(...) debug_out(__VA_ARGS__)
#endif

//////////////// //////////////// //////////////// //////////////// ////////////////
//////////////// //////////////// //////////////// //////////////// ////////////////

typedef tuple<int, int, int> p;

int n;
vector<vector<pair<int, int>>> xyss(2); // (x,y)'s と (y,x)'x
vector<vector<int>> xsys(2); // x's と y's
priority_queue<p, vector<p>, greater<p>> mins; // 距離、0or1(x or y)、(x or y)座標
vector<set<int>> used(2); // 使ったxとy
int res;

int main() {
    // 入出力
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << setprecision(10); // 浮動小数の表示の精度

    cin >> n;
    rep(i, n)
    {
        int x, y;
        cin >> x >> y;
        xyss[0].push_back({x, y});
        xyss[1].push_back({y, x});
        xsys[0].push_back(x);
        xsys[1].push_back(y);
    }
    sort(xyss[0].begin(), xyss[0].end());
    sort(xyss[1].begin(), xyss[1].end());
    sort(xsys[0].begin(), xsys[0].end());
    xsys[0].erase(unique(xsys[0].begin(), xsys[0].end()), xsys[0].end());
    sort(xsys[1].begin(), xsys[1].end());
    xsys[1].erase(unique(xsys[1].begin(), xsys[1].end()), xsys[1].end());
    debug("sorted");

    mins.push({0, 0, xsys[0][0]});
    while (!mins.empty()) {
        int dist, is_xy, x; tie(dist, is_xy, x) = mins.top(); mins.pop();
        if (used[is_xy].find(x) != used[is_xy].end()) { continue; }
        auto& xys = xyss[is_xy];
        auto& xs = xsys[is_xy];
        used[is_xy].insert(x); res += dist;
        // y方向を追加
        for (auto it = lower_bound(xys.begin(), xys.end(), make_pair(x,0)); it != xys.end(); it++) {
            if (it->first != x) { break; }
            int y = it->second;
            if (used[1 - is_xy].find(y) != used[1 - is_xy].end()) { continue; }
            mins.push({0, 1 - is_xy, y});
        }
        // x方向に1つずらしたものを追加
        if (*xs.begin() != x) {
            int xprev = *(lower_bound(xs.begin(), xs.end(), x) - 1);
            if (used[is_xy].find(xprev) == used[is_xy].end())
            {
                mins.push({x - xprev, is_xy, xprev});
            }
        }
        if (*xs.rbegin() != x)
        {
            int xnxt = *(lower_bound(xs.begin(), xs.end(), x) + 1);
            if (used[is_xy].find(xnxt) == used[is_xy].end())
            {
                mins.push({xnxt - x, is_xy, xnxt});
            }
        }
    }
    cout<<res<<'\n';

    return 0;
}


Measured memory_bytes: 16228