// #pragma GCC optimize("O3,unroll-loops") #include // #include using namespace std; #if __cplusplus >= 202002L using namespace numbers; #endif int main(){ cin.tie(0)->sync_with_stdio(0); cin.exceptions(ios::badbit | ios::failbit); auto __solve_tc = [&](auto __tc_num)->int{ int n, len; cin >> n >> len; vector> a(n); for(auto &[x, y]: a){ cin >> x >> y; } auto dist = [&](int i, int j)->int{ return abs(a[i][0] - a[j][0]) + abs(a[i][1] - a[j][1]); }; long long opt = numeric_limits::max(); vector opt_order; { vector order(n); iota(order.begin(), order.end(), 0); ranges::sort(order, [&](int i, int j){ return a[i][0] != a[j][0] ? a[i][0] < a[j][0] : a[i][1] < a[j][1]; }); vector root; vector next(n, -1); vector active; for(auto i: order){ int p = *ranges::partition_point(ranges::iota_view(0, (int)active.size()), [&](int p){ return a[active[p]][1] <= a[i][1]; }); if(p == (int)active.size()){ root.push_back(i); active.push_back(i); } else{ next[active[p]] = i; active[p] = i; } } vector path; for(auto i = 0; i < (int)root.size(); ++ i){ for(auto u = root[i]; ~u; u = next[u]){ path.push_back(u); } } long long cost = 0; for(auto i = 0; i < (int)path.size() - 1; ++ i){ cost += dist(path[i], path[i + 1]); } if(opt > cost){ opt = cost; opt_order = path; } } { vector order(n); iota(order.begin(), order.end(), 0); ranges::sort(order, [&](int i, int j){ return a[i][0] != a[j][0] ? a[i][0] < a[j][0] : a[i][1] > a[j][1]; }); vector root; vector next(n, -1); vector active; for(auto i: order){ int p = *ranges::partition_point(ranges::iota_view(0, (int)active.size()), [&](int p){ return a[active[p]][1] >= a[i][1]; }); if(p == (int)active.size()){ root.push_back(i); active.push_back(i); } else{ next[active[p]] = i; active[p] = i; } } vector path; for(auto i = 0; i < (int)root.size(); ++ i){ for(auto u = root[i]; ~u; u = next[u]){ path.push_back(u); } } long long cost = dist(path[0], path[(int)path.size() - 1]); for(auto i = 0; i < (int)path.size() - 1; ++ i){ cost += dist(path[i], path[i + 1]); } if(opt > cost){ opt = cost; opt_order = path; } } { vector order(n); iota(order.begin(), order.end(), 0); ranges::sort(order, [&](int i, int j){ return a[i][1] != a[j][1] ? a[i][1] < a[j][1] : a[i][0] < a[j][0]; }); vector root; vector next(n, -1); vector active; for(auto i: order){ int p = *ranges::partition_point(ranges::iota_view(0, (int)active.size()), [&](int p){ return a[active[p]][0] <= a[i][0]; }); if(p == (int)active.size()){ root.push_back(i); active.push_back(i); } else{ next[active[p]] = i; active[p] = i; } } vector path; for(auto i = 0; i < (int)root.size(); ++ i){ for(auto u = root[i]; ~u; u = next[u]){ path.push_back(u); } } long long cost = 0; for(auto i = 0; i < (int)path.size() - 1; ++ i){ cost += dist(path[i], path[i + 1]); } if(opt > cost){ opt = cost; opt_order = path; } } { vector order(n); iota(order.begin(), order.end(), 0); ranges::sort(order, [&](int i, int j){ return a[i][1] != a[j][1] ? a[i][1] < a[j][1] : a[i][0] > a[j][0]; }); vector root; vector next(n, -1); vector active; for(auto i: order){ int p = *ranges::partition_point(ranges::iota_view(0, (int)active.size()), [&](int p){ return a[active[p]][0] >= a[i][0]; }); if(p == (int)active.size()){ root.push_back(i); active.push_back(i); } else{ next[active[p]] = i; active[p] = i; } } vector path; for(auto i = 0; i < (int)root.size(); ++ i){ for(auto u = root[i]; ~u; u = next[u]){ path.push_back(u); } } long long cost = dist(path[0], path[(int)path.size() - 1]); for(auto i = 0; i < (int)path.size() - 1; ++ i){ cost += dist(path[i], path[i + 1]); } if(opt > cost){ opt = cost; opt_order = path; } } cout << n << "\n"; for(auto i: opt_order){ cout << a[i][0] << " " << a[i][1] << "\n"; } return 0; }; int __tc_cnt; cin >> __tc_cnt; for(auto __tc_num = 0; __tc_num < __tc_cnt; ++ __tc_num){ __solve_tc(__tc_num); } return 0; } /* */