#include #include #include #include #include #include #include #define N_MAX 200002 using namespace std; typedef long long ll; typedef pair P; const ll MOD = 998244353; struct UnionFind { vector data; UnionFind(int size) : data(size, -1) { } bool unionSet(int x, int y) { x = root(x); y = root(y); if (x != y) { if (data[y] < data[x]) swap(x, y); data[x] += data[y]; data[y] = x; } return x != y; } bool findSet(int x, int y) { return root(x) == root(y); } int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); } int size(int x) { return -data[root(x)]; } }; ll inv[N_MAX],fac[N_MAX],finv[N_MAX]; void init(){ fac[0]=fac[1]=1; finv[0]=finv[1]=1; inv[1]=1; for(int i=2;i mp; ll calc(ll n, ll k){ ll ans = 0; for(ll i = 0; i <= n-k; i++){ if(k+i <= 1) continue; if(k+i == 2 && k == 0) continue; if(k == 1 && i == 1){ ans += comb(n-k, i); continue; } if(k == 2 && i == 0){ ans += 2*comb(n-k, i); continue; } ll tmp = (fac[k+i]*(1<> N >> M; for(int i = 0; i < M; i++) { cin >> a[i] >> b[i]; } mp[P(2, 2)] = 2; mp[P(2, 1)] = 1; ll ans = 0; for(int i = 0; i < (1< st; int c = 0; for(int j = 0; j < M; j++){ if(i&(1< idx; int cur = 0; for(int j : st){ idx[j] = cur; cur++; } UnionFind uf(sz); bool ok = true; for(int j = 0; j < M; j++){ if(i&(1< v_cnt(sz); for(int j = 0; j < M; j++){ if(i&(1< st_root; for(int j = 0; j < sz; j++) { int r = uf.root(j); st_root.insert(r); } int rem = N-sz+st_root.size(); int k = st_root.size(); ll sgn = (c%2 == 0 ? 1 : -1); ll tmp; if(mp.count(P(rem, k)) == 0){ tmp = calc(rem, k); }else{ tmp = mp[P(rem, k)]; } if(k == 1 && uf.size(0) >= 3) tmp++; ans += (sgn*tmp)%MOD; ans %= MOD; } cout << (ans+MOD)%MOD << endl; }