#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#define DIM 200000
#define INF 2000000000
using namespace std;
class InParser {
private:
FILE *fin;
char *buff;
int sp;
char read_ch() {
++sp;
if (sp == 4096) {
sp = 0;
fread(buff, 1, 4096, fin);
}
return buff[sp];
}
public:
InParser(const char* nume) {
fin = fopen(nume, "r");
buff = new char[4096]();
sp = 4095;
}
InParser& operator >> (int &n) {
char c;
while (!isdigit(c = read_ch()) && c != '-');
int sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
InParser& operator >> (long long &n) {
char c;
n = 0;
while (!isdigit(c = read_ch()) && c != '-');
long long sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
};
struct punct{
int x,y,poz;
} v[DIM];
struct muchie{
int x,y,cost;
};
vector <muchie> mch;
int t[DIM],w[DIM];
int T,n,i,j,maxi,sol_poz;
pair <int,int> aint[DIM];
inline int cmp (muchie a, muchie b){
return a.cost < b.cost;
}
inline int cmp2 (punct a, punct b){
if (a.x == b.x)
return a.y < b.y;
return a.x < b.x;
}
int get_rad (int x){
int nr = x;
while (t[x] > 0)
x = t[x];
while (t[nr] > 0){
int aux = t[nr];
t[nr] = x;
nr = aux;
}
return x;
}
int cautare_binara (int v[], int n, int val){
int st = 1, dr = n;
while (st <= dr){
int mid = (st+dr)>>1;
if (v[mid] == val)
return mid;
if (v[mid] < val)
st = mid+1;
else dr = mid-1;
}
}
void build (int nod, int st, int dr){
if (st == dr){
aint[nod] = make_pair (-INF,0);
return;
}
int mid = (st+dr)>>1;
build (nod<<1,st,mid);
build ((nod<<1)|1,mid+1,dr);
aint[nod] = make_pair (-INF,0);
}
void update (int nod, int st, int dr, int poz, pair<int,int> val){
if (st == dr){
if (val.first > aint[nod].first)
aint[nod] = val;
return;
}
int mid = (st+dr)>>1;
if (poz <= mid)
update (nod<<1,st,mid,poz,val);
else update ((nod<<1)|1,mid+1,dr,poz,val);
if (aint[nod<<1].first > aint[(nod<<1)||1].first)
aint[nod] = aint[nod<<1];
else aint[nod] = aint[(nod<<1)|1];
}
void query (int nod, int st, int dr, int x, int y){
if (x <= st && dr <= y){
if (aint[nod].first > maxi)
maxi = aint[nod].first, sol_poz = aint[nod].second;
return;
}
int mid = (st+dr)>>1;
if (x <= mid)
query (nod<<1,st,mid,x,y);
if (y > mid)
query ((nod<<1)|1,mid+1,dr,x,y);
}
void solve(){
int i;
for (i=1;i<=n;++i)
w[i] = v[i].y - v[i].x;
sort (w+1,w+n+1);
int k = 1;
for (i=2;i<=n;++i)
if (w[i] != w[i-1])
w[++k] = w[i];
//memset (aint,0,sizeof aint);
//build (1,1,k);
for (i=1;i<=4*k;++i)
aint[i] = make_pair(-INF,0);
sort (v+1,v+n+1,cmp2);
for (i=1;i<=n;++i){
int poz = cautare_binara (w,k,v[i].y - v[i].x);
maxi = -INF, sol_poz = 0;
query (1,1,k,poz+1,k);
if (sol_poz){
mch.push_back({v[i].poz,sol_poz,v[i].x-v[i].y - maxi});
//cout<<v[i].poz<<" "<<sol_poz<<" "<<v[i].x-v[i].y - maxi<<"\n";
}
update (1,1,k,poz,make_pair(v[i].x - v[i].y,v[i].poz));
}
}
int main (){
ios_base::sync_with_stdio(false);
InParser cin ("metrou4.in");
ofstream cout ("metrou4.out");
cin>>T;
for (;T--;){
cin>>n;
mch.clear();
int el = 0, el2 = 0;
for (i=1;i<=n;++i){
cin>>v[i].x>>v[i].y;
v[i].poz = i;
t[i] = -1;
}
/// trb sa rotesc punctele ca sa reduc la un singur cadran din 8
for (int pas=1;pas<=2;++pas){
for (int pas2=1;pas2<=4;++pas2){
solve();
for (i=1;i<=n;++i){
int x = -v[i].y, y = v[i].x;
v[i].x = x, v[i].y = y;
}
}
for (i=1;i<=n;++i)
v[i].x = -v[i].x;
}
sort (mch.begin(),mch.end(),cmp);
long long sol = 0;
for (auto it : mch){
int x = it.x, y = it.y;
int radx = get_rad(x), rady = get_rad(y);
if (radx != rady){
sol += it.cost;
if (t[radx] > t[rady])
swap (radx,rady);
t[radx] += t[rady];
t[rady] = radx;
}
}
cout<<sol<<"\n";
}
return 0;
} /// :((