#include <bits/stdc++.h>
using namespace std;
ifstream fin("metrou4.in");
ofstream fout("metrou4.out");
const int kN = 1e5 + 5e4;
const int INF = 2e9 + 1;
struct point {
int x, y, index;
void read() {
fin >> x >> y;
}
bool operator < (const point &rhs) const {
if (x != rhs.x) {
return x > rhs.x;
}
return y > rhs.y;
}
} p[kN], aux[kN];
struct ST {
int n;
vector<pair<int, int>> t;
ST(int N) : n(N) {
int dim = 1;
while (dim < n) {
dim *= 2;
}
t.resize(dim * 2, {INF, INF});
}
void update(int x, int lx, int rx, int pos, pair<int, int> v) {
if (lx == rx) {
t[x] = min(t[x], v);
return;
}
int mid = (lx + rx) / 2;
if (pos <= mid) {
update(x * 2, lx, mid, pos, v);
} else {
update(x * 2 + 1, mid + 1, rx, pos, v);
}
t[x] = min(t[x * 2], t[x * 2 + 1]);
}
void update(int pos, pair<int, int> v) {
update(1, 1, n, pos, v);
}
pair<int, int> query(int x, int lx, int rx, int st, int dr) {
if (st <= lx && rx <= dr) {
return t[x];
}
int mid = (lx + rx) / 2;
pair<int, int> ans{INF, INF};
if (st <= mid) {
ans = min(ans, query(x * 2, lx, mid, st, dr));
}
if (mid < dr) {
ans = min(ans, query(x * 2 + 1, mid + 1, rx, st, dr));
}
return ans;
}
pair<int, int> query(int st, int dr) {
return query(1, 1, n, st, dr);
}
};
struct DSU {
vector<int> p, sz;
DSU(int n) {
p.resize(n);
iota(p.begin(), p.end(), 0);
sz.assign(n, 1);
}
int root(int x) {
if (x == p[x]) {
return x;
}
return p[x] = root(p[x]);
}
bool unite(int u, int v) {
int x = root(u), y = root(v);
if (x == y) {
return false;
}
if (sz[y] < sz[x]) {
swap(x, y);
}
p[x] = y;
sz[y] += sz[x];
return true;
}
};
void testCase() {
int n;
fin >> n;
for (int i = 0; i < n; ++i) {
p[i].read();
p[i].index = i;
}
vector<tuple<int, int, int>> edges;
for (int rot = 0; rot < 8; ++rot) {
for (int i = 0; i < n; ++i) {
aux[i] = p[i];
}
vector<int> diff(n);
for (int i = 0; i < n; ++i) {
if (rot & 1) {
p[i].x *= -1;
}
if (rot & 2) {
p[i].y *= -1;
}
if (rot & 4) {
swap(p[i].x, p[i].y);
}
diff[i] = p[i].x - p[i].y;
}
sort(diff.begin(), diff.end());
diff.erase(unique(diff.begin(), diff.end()), diff.end());
sort(p, p + n);
int N = diff.size();
ST t(N);
for (int i = 0; i < n; ++i) {
int index = distance(diff.begin(), upper_bound(diff.begin(), diff.end(), p[i].x - p[i].y));
pair<int, int> ret = t.query(1, index);
if (ret.first != INF) {
edges.emplace_back(ret.first - (p[i].x + p[i].y), p[i].index, ret.second);
}
t.update(index, {p[i].x + p[i].y, p[i].index});
}
for (int i = 0; i < n; ++i) {
p[i] = aux[i];
}
}
sort(edges.begin(), edges.end());
DSU dsu(n);
int64_t ans = 0;
for (auto it : edges) {
int w, u, v;
tie(w, u, v) = it;
if (dsu.unite(u, v)) {
ans += w;
}
}
fout << ans << '\n';
}
int main() {
int tests;
fin >> tests;
for (int tc = 1; tc <= tests; ++tc) {
testCase();
}
fin.close();
fout.close();
return 0;
}