#include <fstream>
//#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
ifstream cin("metrou4.in");
ofstream cout("metrou4.out");
const int MAXN = 150000;
struct Point {
int x, y;
int index;
bool operator < (const Point &other) const {
if (x == other.x)
return y < other.y;
return x < other.x;
}
};
Point v[1 + MAXN];
struct Edge {
int from, to;
int cost;
bool operator < (const Edge &other) const {
return cost < other.cost;
}
};
vector<Edge> edges;
void Rotate(int n) {
for (int i = 1; i <= n; i++) {
int x = v[i].x, y = v[i].y;
v[i].x = -y;
v[i].y = x;
}
}
void Reflect(int n) {
for (int i = 1; i <= n; i++)
v[i].x *= -1;
}
int number[1 + MAXN];
pair<int, int> tree[1 + 4 * MAXN];
void Update(int node, int left, int right, int where, const Point &point) {
if (!tree[node].second || tree[node].first < point.x + point.y)
tree[node] = make_pair(point.x + point.y, point.index);
if (left == right)
return;
int middle = (left + right) / 2;
if (where <= middle)
Update(2 * node, left, middle, where, point);
else
Update(2 * node + 1, middle + 1, right, where, point);
}
pair<int, int> Query(int node, int left, int right, int limit) {
if (right <= limit)
return tree[node];
int middle = (left + right) / 2;
if (limit <= middle)
return Query(2 * node, left, middle, limit);
pair<int, int> answer = Query(2 * node, left, middle, limit), temp = Query(2 * node + 1, middle + 1, right, limit);
if (!answer.second || (temp.second && answer.first < temp.first))
answer = temp;
return answer;
}
void GetEdges(int n) {
for (int i = 1; i <= n; i++)
number[i] = v[i].y - v[i].x;
sort(number + 1, number + n + 1);
sort(v + 1, v + n + 1);
int m = unique(number + 1, number + n + 1) - number - 1;
for (int i = 1; i <= 4 * n; i++)
tree[i] = make_pair(0, 0);
for (int i = 1; i <= n; i++) {
int where = lower_bound(number + 1, number + m + 1, v[i].y - v[i].x) - number;
pair<int, int> answer = Query(1, 1, m, where);
if (answer.second)
edges.push_back({v[i].index, answer.second, v[i].x + v[i].y - answer.first});
Update(1, 1, m, where, v[i]);
}
}
int dad[1 + MAXN], h[1 + MAXN];
void Initialize(int n) {
for (int i = 1; i <= n; i++) {
dad[i] = i;
h[i] = 1;
}
}
int FindDad(int node) {
if (dad[node] == node)
return node;
return dad[node] = FindDad(dad[node]);
}
void Join(int a, int b) {
if (h[a] < h[b])
dad[a] = b;
else {
dad[b] = a;
if (h[a] == h[b])
h[a]++;
}
}
int main() {
int tests;
cin >> tests;
for (int test = 1; test <= tests; test++) {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> v[i].x >> v[i].y;
v[i].index = i;
}
edges.clear();
for (int i = 1; i <= 2; i++) {
for (int j = 1; j <= 4; j++) {
GetEdges(n);
Rotate(n);
}
Reflect(n);
}
Initialize(n);
sort(edges.begin(), edges.end());
long long answer = 0;
for (auto &edge : edges)
if (FindDad(edge.from) != FindDad(edge.to)) {
answer += edge.cost;
Join(FindDad(edge.from), FindDad(edge.to));
}
cout << answer << "\n";
}
return 0;
}