// Arup Guha
// 6/14/2026
// Solution to Kattis Problem: Cheating Students
// https://open.kattis.com/problems/cheatingstudents

using namespace std;

#include <bits/stdc++.h>

struct edge {

    int u;
    int v;
    int w;

    // Here, we define less than, which the priority queue uses.
    // pq's are max queues in c++, so this is pretty weird.
    bool operator<(const edge& other) const {
        return w >= other.w;
    }
};

int prims(vector<vector<edge>>& g, int v);
int manDist(vector<pair<int,int>>& locs, int i, int j);

int main() {

    // Read in all of the points.
    int n;
    cin >> n;
    vector<pair<int,int>> locs(n);
    for (int i=0; i<n; i++)
        cin >> locs[i].first >> locs[i].second;

    // Make the graph.
    vector<vector<edge>> graph(n);

    // Add each edge into the graph.
    for (int i=0; i<n; i++) {
        for(int j=0; j<n; j++) {
            if (i==j) continue;

            // Add this edge.
            edge tmp; tmp.u = i; tmp.v = j; tmp.w = manDist(locs, i, j);
            graph[i].push_back(tmp);
        }
    }

    // Output MST cost or -1 if there's no MST.
    cout << 2*prims(graph, 0) << endl;
    return 0;
}

// Returns the Manhattan distance between locs[i] and locs[j].
int manDist(vector<pair<int,int>>& locs, int i, int j) {
    return abs(locs[i].first-locs[j].first) + abs(locs[i].second-locs[j].second);
}

// Returns the MST of the graph g, starting Prim's algorithm at vertex v.
int prims(vector<vector<edge>>& g, int v) {

    // Set up prims.
    int n = g.size();

    // Store vertices connected.
    vector<bool> used(n, false);

    // Priority Queue of edges to consider, put in edges from v.
    priority_queue<edge> pq;
    used[v] = true;
    for (auto e: g[v])
        pq.push(e);

    // Bookkeeping.
    int numE = 0;
    int cost = 0;

    // We'll handle the disconnected case in the loop.
    while (numE < n-1) {

        // Indicates no MST (not connected).
        if (pq.size() == 0) return -1;

        // Get the next edge.
        edge cur = pq.top(); pq.pop();

        // Doesn't help us get anywhere new.
        if (used[cur.u] && used[cur.v]) continue;

        // Added vertex.
        int nV = !used[cur.u] ? cur.u : cur.v;
        numE++;
        used[nV] = true;
        cost += cur.w;

        // Add edges from this vertex.
        for (auto e: g[nV])
            pq.push(e);
    }

    // Ta da!
    return cost;
}
