#include<bits/stdc++.h> usingnamespace std; constint N = 18,Sz = 1 << 17,M = 400,P = 998244353; inlinevoidPlus(int &x,constint &y){ x += y;if(x >= P) x -= P;} inlineintqpow(int a,int b){ int res = 1;while(b) {if(b&1) res = 1ll * res * a % P;a = 1ll * a * a % P;b >>= 1;} return res;} int n,m; int U[M],V[M];
inlinevoidGetInv(int *f,int *g,int n){ int finv = g[0] = qpow(f[0],P - 2); for(int i = 1;i < n;i++) { int res = 0; for(int j = 1;j <= i;j++) Plus(res,P - 1ll * f[j] * g[i - j] % P); g[i] = 1ll * res * finv % P; } } inlinevoidFWT(int *F,int len,int op){ for(int k = 1;k < len;k <<= 1) for(int j = 0;j < len;j += k + k) for(int i = 0;i < k;i++) if(op == 1) Plus(F[i | j | k],F[i | j]); elsePlus(F[i | j | k],P - F[i | j]); } int siz[Sz]; int fa[N]; intfind(int x){ return fa[x] == x ? x : fa[x] = find(fa[x]);} inlinevoidMerge(int x,int y){ fa[find(x)] = find(y);} inlineintGetcoef(int S){ for(int i = 0;i < n;i++) fa[i] = i; for(int i = 1;i <= m;i++) if((S >> U[i] & 1) && (S >> V[i] & 1)) Merge(U[i],V[i]); int res = 1; for(int i = 0;i < n;i++) if((S >> i & 1) && find(i) == i) ++res; // res = 0; return (res & 1) ? P - 1 : 1; } int f[N][Sz]; int dp[Sz]; intmain(){ cin >> n >> m; for(int i = 1;i <= m;i++) cin >> U[i] >> V[i],--U[i],--V[i]; int all = 1 << n; for(int i = 1;i < all;i++) siz[i] = siz[i >> 1] + (i&1); for(int i = 1;i < all;i++) f[siz[i]][i] = Getcoef(i); // dp[0] = 1; // for(int S = 1;S < all;++S) // for(int T = S;T;T = (T - 1) & S) // Plus(dp[S],1ll * f[siz[T]][T] * dp[S - T] % P); // cout << dp[all - 1] << endl; f[0][0] = 1; for(int i = 1;i < all;i++) f[siz[i]][i] = P - f[siz[i]][i]; for(int i = 0;i <= n;i++) FWT(f[i],all,1); for(int t = 0;t < all;t++) { staticint g[N],h[N]; for(int i = 0;i <= n;i++) g[i] = f[i][t]; GetInv(g,h,n + 1); for(int i = 0;i <= n;i++) f[i][t] = h[i]; } for(int i = 0;i <= n;i++) FWT(f[i],all,-1); cout << f[n][all - 1] << endl; return0; }