#include <bits/stdc++.h>
struct edge {
  long long to;
  long long cost;
};
using namespace std;
using vi = vector<long long>;
using vii = vector<vector<long long>>;
using vb = vector<bool>;
using qi = queue<long long>;
using P = pair<long long, long long>;
using graph = vector<vector<edge>>;
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
const long long inf = 1LL << 60;
const long long mod = 1000000007;
const long long maxn = 100;
long long n;
vi x(maxn);
vi y(maxn);
vb used(maxn);
graph G(maxn);
vi dx = {-1, 0, 0, 1};
vi dy = {0, -1, 1, 0};
long long prim() {
  long long s = 0;
  used.assign(n, false);
  priority_queue<P, vector<P>, greater<P>> pq;
  pq.emplace(0, s);
  long long ret = 0;
  while (!pq.empty()) {
    P p = pq.top();
    pq.pop();
    long long v = p.second;
    if (used[v]) continue;
    used[v] = true;
    ret += p.first;
    for (auto& e : G[v]) pq.emplace(e.cost, e.to);
  }
  return ret;
}
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> n;
  for (long long i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
  }
  vi idx(n);
  vi idy(n);
  for (long long i = 0; i < n; i++) {
    idx[i] = i;
    idy[i] = i;
  }
  sort(idx.begin(), idx.end(),
       [&](long long i, long long j) { return x[i] < x[j]; });
  sort(idy.begin(), idy.end(),
       [&](long long i, long long j) { return y[i] < y[j]; });
  for (long long i = 0; i < n - 1; i++) {
    edge e;
    long long s = idx[i];
    e.to = idx[i + 1];
    e.cost = x[e.to] - x[s];
    G[s].push_back(e);
    swap(e.to, s);
    G[s].push_back(e);
  }
  for (long long i = 0; i < n - 1; i++) {
    edge e;
    long long s = idy[i];
    e.to = idy[i + 1];
    e.cost = y[e.to] - y[s];
    G[s].push_back(e);
    swap(e.to, s);
    G[s].push_back(e);
  }
  long long ret = prim();
  cout << fixed << setprecision(10) << ret << "\n";
}
