intdet(int n) { int res = 1, x = 0; for (int i = 1; i <= n; ++ i) { int t = -1; for (int j = i; j <= n; ++ j) if (a[j][i]) { t = j; break; } if (!~t) return0; if (i ^ t) x ^= 1, std::swap(a[i], a[t]); res = (LL) res * a[i][i] % Mod; LL Inv = qpow(a[i][i]); for (int j = i; j <= n; ++ j) a[i][j] = (LL) a[i][j] * Inv % Mod; for (int j = i + 1; j <= n; ++ j) for (int k = n; k >= i; -- k) a[j][k] = (a[j][k] + (LL) (Mod - a[i][k]) * a[j][i]) % Mod; } return x ? adj(res = -res) : res; }
voidsolve(std::vector<int> all) { if (all.size() == 1) return; int m = all.size(); for (int i = 1; i <= m; ++ i) for (int j = 1; j <= m; ++ j) if (i != j) a[i][j] = bew[all[i - 1]][all[j - 1]]; else a[i][j] = 0; for (int i = 1; i <= m; ++ i) { int t = 0; for (int j = 1; j <= m; ++ j) t += a[i][j]; for (int j = 1; j <= m; ++ j) if (a[i][j]) a[i][j] = Mod - a[i][j]; a[i][i] = t; } /*for (int i = 1; i <= m; ++ i, puts("")) for (int j = 1; j <= m; ++ j) printf("%d ", a[i][j]);*/ int ans = det(m - 1); for (int &x : all) ans = (LL) ans * g[x] % Mod; /*for (int x : all) printf("%d ", x); printf(": %d\n", ans);*/ adj(res += ans - Mod); }
voiddfs(int s, std::vector<int> &all) { if (!s) returnsolve(all); // std::cout << s << ' ' << all.size() << '\n'; all.push_back(0); int t = ctz(s); for (int s2 = s; s2; s2 = (s2 - 1) & s) { if (!(s2 >> t & 1)) continue; all.back() = s2; dfs(s ^ s2, all); } all.pop_back(); }
voidwork() { std::cin >> n >> m; ban.clear(); for (int i = 1, u, v; i <= m; ++ i) { std::cin >> u >> v; if (u > v) std::swap(u, v); ban.insert({-- u, -- v}); }
for (int i = 0; i < n; ++ i) for (int j = 0; j < n; ++ j) if (i >= j || ban.count({i, j})) a[i][j] = 0; else a[i][j] = 1; for (int s = 0; s < (1 << n); ++ s) ins[s] = 0; for (int s1 = 0; s1 < (1 << n); ++ s1) for (int s2 = 0; s2 < (1 << n); ++ s2) bew[s1][s2] = 0; for (int i = 0; i < n; ++ i) for (int j = 0; j < n; ++ j) if (a[i][j]) ins[(1 << i) | (1 << j)] ++; for (int i = 0; i < n; ++ i) for (int j = 0; j < i; ++ j) bew[1 << i][1 << j] = bew[1 << j][1 << i] = a[j][i];
for (int i = 0; i < n; ++ i) for (int s1 = 0; s1 < (1 << n); ++ s1) if (s1 >> i & 1) for (int s2 = 0; s2 < (1 << n); ++ s2) bew[s1][s2] += bew[s1 ^ (1 << i)][s2]; for (int i = 0; i < n; ++ i) for (int s2 = 0; s2 < (1 << n); ++ s2) if (s2 >> i & 1) for (int s1 = 0; s1 < (1 << n); ++ s1) bew[s1][s2] += bew[s1][s2 ^ (1 << i)]; for (int i = 0; i < n; ++ i) for (int s = 0; s < (1 << n); ++ s) if (s >> i & 1) ins[s] += ins[s ^ (1 << i)]; for (int s = 1; s < (1 << n); ++ s) { f[s] = pw2[ins[s]]; int t = ctz(s); for (int s2 = s & (s - 1); s2; s2 = (s2 - 1) & s) if (s2 >> t & 1) f[s] = (f[s] + (LL) (Mod - f[s2]) * pw2[ins[s ^ s2]]) % Mod; } std::vector<int> tmp; for (int s = 1; s < (1 << n); ++ s) res = 0, dfs(s, tmp), adj(g[s] = f[s] - res); // for (int s = 1; s < (1 << n); ++ s) printf("%d ", g[s]); std::cout << g[(1 << n) - 1] << '\n'; }