#include <bits/stdc++.h>
const long long MAX = 1000000007;
using namespace std;
struct Town {
  long long i;
  long long x;
  long long y;
  Town() {}
  Town(long long _i, long long _x, long long _y) {
    i = _i;
    x = _x;
    y = _y;
  }
  static bool greater_x(const Town& t0, const Town& t1) { return t0.x < t1.x; }
  static bool greater_y(const Town& t0, const Town& t1) { return t0.y < t1.y; }
};
struct UnionFind {
  const long long N;
  vector<long long> parent;
  vector<long long> rank;
  UnionFind(long long n) : N(n) {
    parent = vector<long long>(N);
    rank = vector<long long>(N, 0);
    for (size_t i = 0; i < N; i++) {
      parent[i] = i;
    }
  }
  int root(long long i) {
    return parent[i] == i ? i : parent[i] = root(parent[i]);
  }
  bool same(long long i, long long j) { return root(i) == root(j); }
  void unite(long long i, long long j) {
    i = root(i);
    j = root(j);
    if (i == j) {
      return;
    }
    if (rank[i] < rank[j]) {
      parent[i] = j;
    } else {
      parent[j] = i;
      if (rank[i] == rank[j]) {
        rank[i]++;
      }
    }
  }
  bool isOne() {
    for (size_t i = 1; i < N; i++) {
      if (!same(0, i)) {
        return false;
      }
    }
    return true;
  }
};
template <typename T>
struct Graph {
  struct Node {
    T value;
    Node(T _value) { value = _value; }
  };
  struct Edge {
    long long i;
    long long j;
    long long cost;
    Edge(long long _i, long long _j, long long _cost) {
      i = _i;
      j = _j;
      cost = _cost;
    }
    static bool greater(const Edge& e0, const Edge& e1) {
      return e0.cost < e1.cost;
    }
  };
  vector<Node> nodes;
  vector<Edge> edges;
  void add(Node node) { nodes.push_back(node); }
  void add(Edge edge) { edges.push_back(edge); }
  long long getMSTLength() {
    long long ret = 0;
    sort(edges.begin(), edges.end(), Edge::greater);
    UnionFind uf(nodes.size());
    for (size_t i = 0; i < edges.size(); i++) {
      if (uf.isOne()) {
        break;
      }
      if (!uf.same(edges[i].i, edges[i].j)) {
        uf.unite(edges[i].i, edges[i].j);
        ret += edges[i].cost;
      }
    }
    return ret;
  }
};
signed main() {
  long long N;
  long long ret = 0;
  cin >> N;
  vector<long long> x(N);
  vector<long long> y(N);
  for (size_t i = 0; i < N; i++) {
    cin >> x[i] >> y[i];
  }
  vector<Town> vt(N);
  Graph<Town> graph;
  for (size_t i = 0; i < N; i++) {
    Town t(i, x[i], y[i]);
    graph.add(Graph<Town>::Node(t));
    vt[i] = t;
  }
  sort(vt.begin(), vt.end(), Town::greater_x);
  for (size_t i = 0; i < N - 1; i++) {
    graph.add(Graph<Town>::Edge(vt[i].i, vt[i + 1].i, vt[i + 1].x - vt[i].x));
  }
  sort(vt.begin(), vt.end(), Town::greater_y);
  for (size_t i = 0; i < N - 1; i++) {
    graph.add(Graph<Town>::Edge(vt[i].i, vt[i + 1].i, vt[i + 1].y - vt[i].y));
  }
  ret = graph.getMSTLength();
  cout << ret;
  return 0;
}
