#include <bits/stdc++.h>
#define eb emplace_back
#define ep emplace
#define fi first
#define se second
#define in read<int>()
#define lin read<ll>()
#define rep(i, x, y) for(int i = (x); i <= (y); i++)
#define per(i, x, y) for(int i = (x); i >= (y); i--)
using namespace std;
using ll = long long;
using db = double;
using pii = pair < int, int >;
using vec = vector < int >;
using veg = vector < pii >;
template < typename T > T read() {
T x = 0; bool f = 0; char ch = getchar();
while(!isdigit(ch)) f |= ch == '-', ch = getchar();
while(isdigit(ch)) x = x * 10 + (ch ^ 48), ch = getchar();
return f ? -x : x;
}
template < typename T > void chkmax(T &x, const T &y) { x = x > y ? x : y; }
template < typename T > void chkmin(T &x, const T &y) { x = x < y ? x : y; }
const int N = 2e5 + 10;
int n, x[N], y[N];
set < int > pt[N << 1];
set < pii > all;
pii hav[N];
bool vis[N], pvis[N];
struct valpot {
int t[N], tot;
void reset() { tot = 0; }
void ins(int x) { t[++tot] = x; }
void build() { sort(t + 1, t + tot + 1), tot = unique(t + 1, t + tot + 1) - t - 1; }
int operator [](int x) { return lower_bound(t + 1, t + tot + 1, x) - t; }
} a, b;
void solve() {
a.reset(), b.reset();
n = in * 2; rep(i, 1, n) x[i] = in, y[i] = in, vis[i] = pvis[i] = 0, a.ins(x[i]), b.ins(y[i]);
a.build(), b.build();
rep(i, 1, n) x[i] = a[x[i]], y[i] = b[y[i]];
int at = a.tot, bt = b.tot;
rep(i, 1, at + bt) set < int >().swap(pt[i]);
set < pii >().swap(all);
rep(i, 1, n) hav[i] = { x[i], y[i] + at }, pt[x[i]].ep(i), pt[y[i] + at].ep(i);
rep(i, 1, at + bt) all.ep(pt[i].size(), i);
auto del = [&](int id) {
if(!vis[id]) vis[id] = true; else return;
pt[x[id]].erase(id), pt[y[id] + at].erase(id);
all.erase({ pt[x[id]].size() + 1, x[id] });
all.erase({ pt[y[id] + at].size() + 1, y[id] + at });
if(pt[x[id]].size()) all.ep(pt[x[id]].size(), x[id]);
if(pt[y[id] + at].size()) all.ep(pt[y[id] + at].size(), y[id] + at);
};
veg ans; int cnt = 0;
auto pairit = [&](int a, int b) {
pvis[a] = pvis[b] = 1; ans.eb(a, b); cnt += x[a] == x[b] || y[a] == y[b];
del(a), del(b);
};
while(all.size()) {
auto x = *all.begin(); //assert(x.fi >= 1);
if(x.fi == 1) {
int id = *pt[x.se].begin();
int tid = hav[id].fi ^ hav[id].se ^ x.se;
del(id); if(pt[tid].size() == 0) continue;
int nid = *pt[tid].begin();
pairit(id, nid);
} else {
int id = *pt[x.se].begin(), nid = *pt[x.se].rbegin();
pairit(id, nid);
}
}
int lst = 0;
rep(i, 1, n)
if(!pvis[i]) {
if(!lst) lst = i;
else pairit(lst, i), lst = 0;
}
printf("%d\n", cnt);
for(auto v : ans) printf("%d %d\n", v.fi, v.se);
}
int main() {
#ifdef YJR_2333_TEST
freopen("1.in", "r", stdin);
#endif
for(int T = in; T; T--) solve(); return 0;
}