#include <bits/stdc++.h>
using namespace std;
char _buf[11 * 1000000 + 3];
int loadint() {
  fgets(_buf, 11 + 3, stdin);
  return atoi(_buf);
}
int loadvec(vector<int>& v, int N) {
  int bufsize = 11 * N + 3;
  fgets(_buf, bufsize, stdin);
  v.resize(N);
  int i = 0;
  bool last = false;
  for (char* p = &_buf[0];;) {
    char* q = p;
    while (*q > ' ') ++q;
    if (*q == 0x0D || *q == 0x0A) last = true;
    *q = 0;
    v[i++] = atoi(p);
    if (last || i == N) break;
    p = q + 1;
  }
  return i;
}
class UnionFind {
  vector<int> data;

 public:
  UnionFind(int size) : data(size, -1) {}
  bool unionSet(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};
long long solve(int n, vector<int>& x, vector<int>& y) {
  assert(x.size() == n && y.size() == n);
  vector<bool> vis(n, false);
  multimap<int, int> xx, xxv, xxa, yy, yyv, yya;
  multimap<int, pair<int, int> > ox;
  multimap<int, pair<int, int> > oy;
  vis[0] = true;
  long long cost = 0;
  auto initialize = [](int n, vector<bool>& vis, vector<int>& x,
                       multimap<int, int>& xx, multimap<int, int>& xxv,
                       multimap<int, int>& xxa,
                       multimap<int, pair<int, int> >& ox, const char* x_y) {
    for (int i = 0; i < (n); ++i) {
      xx.insert(pair<int, int>(x[i], i));
      if (vis[i]) {
        xxv.insert(pair<int, int>(x[i], i));
      } else {
        xxa.insert(pair<int, int>(x[i], i));
      }
    }
    int i_at_lastV = -1, xi_at_lastV = -1;
    int i_at_lastA = -1, xi_at_lastA = -1;
    for (auto xxj : xx) {
      int xi = xxj.first, i = xxj.second;
      if (vis[i]) {
        if (i_at_lastA != -1) {
          assert(i != i_at_lastA);
          int d = abs(xi - xi_at_lastA);
          ox.insert(
              pair<int, pair<int, int> >(d, pair<int, int>(i, i_at_lastA)));
        }
        i_at_lastV = i;
        xi_at_lastV = xi;
      } else {
        if (i_at_lastV != -1) {
          assert(i != i_at_lastV);
          int d = abs(xi_at_lastV - xi);
          ox.insert(
              pair<int, pair<int, int> >(d, pair<int, int>(i_at_lastV, i)));
        }
        i_at_lastA = i;
        xi_at_lastA = xi;
      }
    }
  };
  initialize(n, vis, x, xx, xxv, xxa, ox, "x");
  initialize(n, vis, y, yy, yyv, yya, oy, "y");
  for (int z = 1; z < n; ++z) {
    auto take_the_smallest = [](vector<bool>& vis,
                                multimap<int, pair<int, int> >& ox,
                                long long& cost, int& v, int& a) {
      auto ox0 = ox.begin();
      if (ox0 == ox.end()) {
        v = a = -1;
        return;
      }
      while (vis[ox0->second.second]) ++ox0;
      cost += ox0->first;
      v = ox0->second.first;
      a = ox0->second.second;
    };
    auto fn0 = [](vector<bool>& vis, multimap<int, pair<int, int> >& ox) {
      for (auto ax = ox.begin(); ax != ox.end(); ++ax) {
        if (!vis[ax->second.second]) {
          return ax->first;
        }
      }
      return 0x7fffffff;
    };
    int x_nearest = fn0(vis, ox);
    int y_nearest = fn0(vis, oy);
    if (x_nearest == 0x7fffffff && y_nearest == 0x7fffffff) {
      assert(false);
    }
    int v, a;
    if (x_nearest < y_nearest) {
      take_the_smallest(vis, ox, cost, v, a);
    } else {
      take_the_smallest(vis, oy, cost, v, a);
    }
    vis[a] = true;
    {
      auto move_a_from_xxa_to_xxv =
          [](vector<int>& x, multimap<int, int>& xxa, multimap<int, int>& xxv,
             int a, const char* x_y) { xxv.insert(pair<int, int>(x[a], a)); };
      move_a_from_xxa_to_xxv(x, xxa, xxv, a, "x");
      move_a_from_xxa_to_xxv(y, yya, yyv, a, "y");
      auto update_ox =
          [](vector<bool>& vis, vector<int>& x, multimap<int, int>& xxa,
             multimap<int, pair<int, int> >& ox, int a, const char* x_y) {
            auto ax = xxa.lower_bound(x[a]), bx = ax;
            while (ax != xxa.end()) {
              int i = ax->second;
              if (i != a && !vis[i]) {
                ox.insert(pair<int, pair<int, int> >(abs(x[a] - x[i]),
                                                     pair<int, int>(a, i)));
                break;
              }
              if (ax == xxa.begin()) break;
              --ax;
            }
            while (bx != xxa.end()) {
              int i = bx->second;
              if (i != a && !vis[i]) {
                ox.insert(pair<int, pair<int, int> >(abs(x[a] - x[i]),
                                                     pair<int, int>(a, i)));
                break;
              }
              ++bx;
            }
          };
      update_ox(vis, x, xxa, ox, a, "x");
      update_ox(vis, y, yya, oy, a, "y");
    }
  }
  return cost;
}
int main() {
  int N = loadint();
  vector<int> tmp(2);
  vector<int> x(N), y(N);
  for (int i = 0; i < (N); ++i) {
    loadvec(tmp, 2);
    x[i] = tmp[0];
    y[i] = tmp[1];
  }
  printf("%lld\n", solve(N, x, y));
  return 0;
}
