for (int i = 1; i <= m; i++) { int u = read(), v = read(); if (bad[u] and bad[v]) { ans++; continue; } g[u].eb(v); g[v].eb(u);
if (u > v) swap(u, v); if (u != v) mp[{u, v}]++; else f[u]++; // mp[{v, u}]++; }
for (int i = 1; i <= k; i++) { if (bad[i]) continue; for (int v : g[i]) { if (bad[v]) { f[i]++; } } // f[i] += mp[{i, i}]; }
int res = 0; for (auto [it, cnt] : mp) { auto [u, v] = it; if (!bad[u] and !bad[v]) res = max(res, f[u] + f[v] + cnt); else res = max(res, f[u] + f[v]); }
for (int i = 1; i <= n; i++) { int ls, rs; cin >> ls >> rs; cout.flush();
if (ls) { g[i].pb(ls); g[ls].pb(i); } if (rs) { g[i].pb(rs); g[rs].pb(i); } }
vector<int> siz(n + 1); vector<int> w(n + 1);
int p = 1, tot = n; vector<int> ban(n + 1);
std::function<void(int, int)> dfs1 = [&](int u, int fa) { siz[u] = 1; for (int v : g[u]) { if (ban[v] or v == fa) continue; dfs1(v, u); siz[u] += siz[v]; } }; std::function<void(int, int)> dfs2 = [&](int u, int fa) { w[u] = 0; for (int v : g[u]) { if (ban[v] or v == fa) continue; dfs2(v, u); w[u] = max(w[u], siz[v]); } w[u] = max(w[u], tot - siz[u]); if (w[u] <= tot / 2) { p = u; } };
using std::endl; auto qry = [&](int x, int y) { cout << "? " << x << " " << y << endl; cout.flush(); int t; cin >> t; cout.flush(); return t; };
while (tot > 1) { dfs1(p, 0); tot = siz[p]; dfs2(p, 0);
int d = 0; for (int v : g[p]) { if (!ban[v]) d++; }
if (d == 0) { cout << "! " << p << endl; cout.flush(); return; } elseif (d == 1) { int x = p, y = 0; for (int tmp : g[p]) { if (!ban[tmp]) { y = tmp; break; } }
int t = qry(x, y); if (t == 0) { cout << "! " << x << endl; cout.flush(); return; } elseif (t == 2) { ban[x] = 1; p = y; } } elseif (d == 2) { int x = 0, y = 0; for (int v : g[p]) { if (!ban[v]) { if (!x) x = v; else y = v; } }
int t = qry(x, y); if (t == 0) { ban[p] = ban[y] = 1; p = x; } elseif (t == 1) { cout << "! " << p << endl; cout.flush(); return; } else { ban[p] = ban[x] = 1; p = y; } } elseif (d == 3) { int x = g[p][0], y = g[p][1], z = g[p][2]; int sx = siz[x], sy = siz[y], sz = siz[z];
if (sx < sy) swap(x, y), swap(sx, sy); if (sx < sz) swap(x, z), swap(sx, sz); if (sy < sz) swap(y, z), swap(sy, sz);
int t = qry(x, y); if (t == 1) { ban[x] = ban[y] = 1; } elseif (t == 0) { ban[y] = ban[z] = ban[p] = 1; p = x; } else { ban[p] = ban[x] = ban[z] = 1; p = y; } }
for (int i = 1; i <= n; i++) { ndp[i] *= comb.binom(n - i - siz[u], siz[fa] - siz[u] - 1); } for (int i = 1; i <= n; i++) { ndp[i] += ndp[i - 1]; } for (int i = 1; i <= n; i++) { dp[u][i] = coef * ndp[i - 1]; } }
for (int i = 1; i <= n; i++) { Z res = dp[i][i]; res *= comb.binom(n - i, siz[i] - 1); res *= comb.fac(siz[i]) / prod[i]; cout << res << " \n"[i == n]; } }
vector<int> a(n * m + 1); for (int i = 1; i <= n * m; i++) { a[i] = read(); }
std::sort(a.begin(), a.end());
Poly<P> f, g; f.resize(n * m + 1); g.resize(n * m); for (int i = 1; i <= n * m; i++) { f[i] = a[i] * comb.fac(i - 1); } for (int i = 0; i < n * m; i++) { g[i] = comb.invfac(n * m - 1 - i); }
f *= g; f = f.shift(- (n * m - 1)); for(int i = 1; i <= n * m; i++) { f[i] *= i * comb.fac(n * m - i); }
Z ans = 0; for (int x = 0; x <= n; x++) { for (int y = 0; y <= m; y++) { if (x + y == 0) { continue; }
Z coef = (x + y - 1) % 2 == 0 ? 1 : -1;
Z res = coef * comb.binom(n, x) * comb.binom(m, y); res *= f[m * x + n * y - x * y];
/* Z t = 0; for (int i = 1; i <= n * m; i++) { t += comb.binom(i - 1, c - 1) * comb.fac(c) * comb.fac(n * m - c) * a[i]; } res *= t; */