#include <fstream>
#include <algorithm>
#define lint long long int
using namespace std;
const int NMAX = 150005;
int n;
struct Point {
int x, y;
int ind;
Point(int _x = 0, int _y = 0, int _ind = 0):
x(_x), y(_y), ind(_ind) {}
} points[NMAX];
bool operator<(const Point &a, const Point &b) {
if (a.x != b.x)
return a.x < b.x;
return a.y < b.y;
}
void reflect() {
for (int i = 1; i <= n; ++ i)
points[i].x = -points[i].x;
}
void rotate() {
for (int i = 1; i <= n; ++ i) {
int old_x = points[i].x;
int old_y = points[i].y;
points[i].x = -old_y;
points[i].y = old_x;
}
}
struct Node {
int st, dr;
int best;
int ind_best;
Node *left, *right;
Node(int _st = 0, int _dr = 0, int _best = 0, int _ind_best = 0, Node *_left = NULL, Node *_right = NULL):
st(_st), dr(_dr), best(_best), ind_best(_ind_best), left(_left), right(_right) {}
~Node() {
if (left != NULL)
delete left;
if (right != NULL)
delete right;
}
void add_point(const Point &p) {
if (!ind_best || p.x + p.y > best)
best = p.x + p.y, ind_best = p.ind;
}
} *root;
void update(Node *node, int where, const Point &p) {
node -> add_point(p);
if (node -> st == node -> dr)
return ;
int mid = (node -> st + node -> dr) >> 1;
if (where <= mid) {
if (node -> left == NULL)
node -> left = new Node(node -> st, mid);
update(node -> left, where, p);
}
else {
if (node -> right == NULL)
node -> right = new Node(mid + 1, node -> dr);
update(node -> right, where, p);
}
}
pair <int, int> query(Node *node, int where) {
if (node -> dr == where)
return make_pair(node -> best, node -> ind_best);
int mid = (node -> st + node -> dr) >> 1;
pair <int, int> ans = make_pair(0, 0);
if (where <= mid) {
if (node -> left != NULL)
ans = query(node -> left, where);
}
else {
pair <int, int> aux;
if (node -> left != NULL) {
aux = query(node -> left, mid);
if (!ans.second || (aux.second && aux.first > ans.first))
ans = aux;
}
if (node -> right != NULL) {
aux = query(node -> right, where);
if (!ans.second || (aux.second && aux.first > ans.first))
ans = aux;
}
}
return ans;
}
int father[NMAX];
int h[NMAX];
void init() {
for (int i = 1; i <= n; ++ i)
father[i] = i, h[i] = 0;
}
int find(int node) {
if (father[node] != father[father[node]])
father[node] = find(father[node]);
return father[node];
}
bool unite(int a, int b) {
a = find(a), b = find(b);
if (a == b)
return false;
if (h[a] < h[b])
father[a] = b;
else {
if (h[a] == h[b])
++ h[a];
father[b] = a;
}
return true;
}
int m;
struct Edge {
int a, b, c;
Edge(int _a = 0, int _b = 0, int _c = 0): a(_a), b(_b), c(_c) {}
} edges[8 * NMAX];
bool operator<(const Edge &a, const Edge &b) {
return a.c < b.c;
}
void sweep() {
sort(points + 1, points + n + 1);
root = new Node(-1000000000, 1000000000);
pair <int, int> aux;
for (int i = 1; i <= n; ++ i) {
aux = query(root, points[i].y - points[i].x);
if (aux.second)
edges[++ m] = Edge(points[i].ind, aux.second, points[i].x + points[i].y - aux.first);
update(root, points[i].y - points[i].x, points[i]);
}
delete root;
}
void get_edges() {
m = 0;
for (int k = 0; k < 2; ++ k) {
for (int i = 0; i < 4; ++ i) {
sweep();
rotate();
}
reflect();
}
}
lint kruskal() {
sort(edges + 1, edges + m + 1);
init();
lint ans = 0;
for (int i = 1; i <= m; ++ i)
if (unite(edges[i].a, edges[i].b))
ans += edges[i].c;
return ans;
}
int main()
{
ifstream cin("metrou4.in");
ofstream cout("metrou4.out");
int t = 1;
cin >> t;
while (t --) {
cin >> n;
for (int i = 1; i <= n; ++ i) {
cin >> points[i].x >> points[i].y;
points[i].ind = i;
}
get_edges();
cout << kruskal() << '\n';
}
cin.close();
cout.close();
return 0;
}