#include <bits/stdc++.h>
long long int N;
std::vector<std::pair<long long int, long long int>> xy;
long long int ans;
struct UnionFind {
  std::vector<int> par;
  std::vector<int> sizes;
  UnionFind(int n) : par(n), sizes(n, 1) {
    for (int i = 0; i < n; ++i) par[i] = i;
  }
  int find(int x) {
    if (x == par[x]) return x;
    return par[x] = find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (sizes[x] < sizes[y]) std::swap(x, y);
    par[y] = x;
    sizes[x] += sizes[y];
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return sizes[find(x)]; }
};
struct Edge {
  int a, b, cost;
  bool operator<(const Edge& o) const { return cost < o.cost; }
};
struct Graph {
  int n;
  std::vector<Edge> es;
  int kruskal() {
    sort(es.begin(), es.end());
    UnionFind uf(n);
    int min_cost = 0;
    for (int ei = 0; ei < es.size(); ++ei) {
      Edge& e = es[ei];
      if (!uf.same(e.a, e.b)) {
        min_cost += e.cost;
        uf.unite(e.a, e.b);
      }
    }
    return min_cost;
  }
};
Graph input_graph() {
  Graph g;
  g.n = (1 + N) * N / 2;
  for (int i = 0; i < N; ++i) {
    for (int j = i + 1; j < N; ++j) {
      Edge e;
      e.a = (i + 1);
      e.b = (j + 1);
      e.cost = std::min(abs(xy[i].first - xy[j].first),
                        abs(xy[i].second - xy[j].second));
      g.es.push_back(e);
    }
  }
  return g;
}
int main() {
  std::cin >> N;
  for (int i = 0; i < N; ++i) {
    long long int x, y;
    std::cin >> x >> y;
    xy.push_back({x, y});
  }
  Graph g = input_graph();
  std::cout << g.kruskal() << std::endl;
  return 0;
}
