#include //can be done by prefix sum const long long mod = 998244353; struct Edge{ int u,v; }; Edge e[35]; long long f[100005], invf[100005]; //sum[i][j]: i segment & j node used long long sum[40][40]; Edge edge[35]; int in[100005]; int queue[50]; long long power(long long a,long long b){ long long res = 1; while(b){ if(b&1) res = res*a%mod; a = a*a%mod; b /= 2; } return res; } long long inv(long long u){ return power(u,mod-2); } long long comb(int n,int m){ if(m>n || m<0) return 0; else{ return f[n]*invf[n-m]%mod*invf[m]%mod; } } int min(int a,int b){ return a>b?b:a; } int max(int a,int b){ return a>b?a:b; } void preWork(int n,int m){ f[0] = invf[0] = 1; for(long long i = 1; i <= n; i++){ f[i] = f[i-1]*i%mod; invf[i] = inv(f[i]); } for(int i = 1; i <= m; i++){ for(int j = 2; j <= 2*m; j++){ sum[i][j] = 0; int start = -1; if(i==1 && j==2) start = 1; else start = 0; for(int k = start; k <= n-j; k++){ long long add = power(2,i-1)%mod*comb(n-j,k)%mod*f[i-1+k]%mod; sum[i][j] = (sum[i][j]+add)%mod; } } } for(int i = 1; i <= m; i++){ //for(int j = i+1; j <= 2*i; j++) printf("sum[%d][%d] = %lld\n",i,j,sum[i][j]); } } int p[100005]; int vis[100005]; int find(int u){ if(p[u]==u) return u; else return p[u] = find(p[u]); } struct Graph{ int x,y; //for i,j int ok; Graph(int x=0,int y=0,int ok=0):x(x),y(y),ok(ok){} }; Graph getGraph(int n){ Graph res; int ok = 1, cycle = 0, node = 0; for(int i = 1; i <= n; i++){ int u = edge[i].u, v = edge[i].v; if(!vis[u]) vis[u] = 1, queue[++node] = u; if(!vis[v]) vis[v] = 1, queue[++node] = v; in[u]++; in[v]++; if(in[u]>2) ok = 0; int x = find(u), y = find(v); if(x==y) cycle++; p[x] = y; } if(!ok || cycle>1) res = Graph(0,0,0); if(cycle==1){ res = Graph(0,0,-1); int root = find(queue[1]); for(int i = 2; i <= node; i++){ int u = find(queue[i]); if(u!=root) res = Graph(0,0,0); } } else{ int seg = 0; for(int i = 1; i <= node; i++){ int u = find(queue[i]), eq = 0; for(int j = i+1; j <= node; j++){ if(find(queue[j])==u) eq = 1; } if(!eq) seg++; } res = Graph(seg,node,ok); } for(int i = 1; i <= node; i++){ int u = queue[i]; in[u] = 0, p[u] = u; vis[u] = 0; } return res; } int main(){ int n,m; scanf("%d%d",&n,&m); preWork(n,m); for(int i = 1; i <= m; i++){ scanf("%d%d",&e[i].u,&e[i].v); } long long answer = 0; for(int i = 3; i <= n; i++){ long long cur = comb(n,i)*f[i-1]%mod*inv(2)%mod; //printf("i = %d, cur = %lld\n",i,cur); answer = (answer+cur)%mod; } //printf("answer = %lld\n",answer); long long sign = mod-1; for(int i = 1; i <= n; i++) p[i] = i, vis[i] = 0; for(int i = 1; i < (1<