#include using namespace std; int N; int query(int u, int v) { cout << "? " << u << " " << v << endl; fflush(stdout); int d; cin >> d; return d; } void reconstruct(const vector& S, vector>& edges) { size_t sz = S.size(); if (sz <= 1) return; if (sz == 2) { int u = S[0], v = S[1]; int w = query(u, v); edges.emplace_back(u, v, w); return; } int u0 = S[0]; vector dist_u(N + 1, -1); int max_d = -1; int far1 = u0; for (int v : S) { if (v == u0) continue; int d = query(u0, v); dist_u[v] = d; if (d > max_d) { max_d = d; far1 = v; } } vector dist_f1(N + 1, -1); dist_f1[far1] = 0; int max_d2 = -1; int far2 = far1; for (int v : S) { if (v == far1) continue; int d = query(far1, v); dist_f1[v] = d; if (d > max_d2) { max_d2 = d; far2 = v; } } int D = max_d2; vector dist_f2(N + 1, -1); dist_f2[far2] = 0; for (int v : S) { if (v == far2) continue; int d = query(far2, v); dist_f2[v] = d; } vector path; for (int x : S) { int dv = dist_f1[x]; int dw = dist_f2[x]; if (dv + dw == D) { path.push_back(x); } } sort(path.begin(), path.end(), [&](int a, int b) { return dist_f1[a] < dist_f1[b]; }); for (size_t i = 0; i + 1 < path.size(); ++i) { int a = path[i]; int b = path[i + 1]; int w = dist_f1[b] - dist_f1[a]; edges.emplace_back(a, b, w); } map pos_to_p; for (int p : path) { pos_to_p[dist_f1[p]] = p; } vector> subs(path.size()); for (int x : S) { auto it_path = find(path.begin(), path.end(), x); if (it_path != path.end()) continue; long long dvx = dist_f1[x]; long long dwx = dist_f2[x]; long long num = dvx + D - dwx; if (num % 2 != 0) continue; long long pos = num / 2; auto it = pos_to_p.find(pos); if (it != pos_to_p.end()) { int att = it->second; int idx = -1; for (int j = 0; j < (int)path.size(); ++j) { if (path[j] == att) { idx = j; break; } } if (idx != -1) { subs[idx].push_back(x); } } } for (size_t i = 0; i < path.size(); ++i) { vector subS; subS.push_back(path[i]); for (int ss : subs[i]) { subS.push_back(ss); } if (subS.size() > 1) { reconstruct(subS, edges); } } } int main() { ios::sync_with_stdio(false); cin.tie(NULL); int T; cin >> T; for (int t = 0; t < T; ++t) { int n; cin >> n; N = n; vector nodes(n); for (int i = 0; i < n; ++i) nodes[i] = i + 1; vector> edges; reconstruct(nodes, edges); cout << "!"; for (auto [u, v, w] : edges) { cout << " " << u << " " << v << " " << w; } cout << endl; fflush(stdout); } return 0; }