#include<bits/stdc++.h>
#include<atcoder/all>
using namespace atcoder;
using mint=modint998244353;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define pii pair<ll,ll>
#define rep(i,a,b) for(ll i=(a);i<=(b);++i)
#define per(i,a,b) for(ll i=(a);i>=(b);--i)
using namespace std;
bool Mbe;
inline ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline void write(ll x){
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
}
//把边双缩起来
//有一棵树,对于每对点,可以连一条非树边覆盖这对点路径上所有边,问有多少种方案
//容斥,枚举某些边断开不覆盖,剩下边之间随便连
//dp,设 f_{u,i} 为子树 u,目前连通块大小为 i (大小指所有边双的大小之和)的(乘上了容斥系数的)和
//枚举儿子 f_{v,j},如果转移到 i+j,系数为 1,乘上 u v 之间乱连的方案数,如果转移到 i,系数为 -1
const ll N=5009;
ll n,m,dfn[N],low[N],tim,bel[N],cnt,sz[N];
ll cut[N<<1],hd[N],tot,esc[N],sc[N];
mint dp[N][N],pw2[N*N],tmp[N];
struct Edg{
ll to,nxt;
}E[N<<1];
void adde(ll x,ll y){
E[++tot]=(Edg){y,hd[x]};
hd[x]=tot;
}
void tarjan(ll u,ll fa){
dfn[u]=low[u]=++tim;
for(ll i=hd[u];i;i=E[i].nxt){
ll v=E[i].to;
if(!dfn[v]){
tarjan(v,i);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u])cut[i]=cut[i^1]=1;
}
else if((i^fa)!=1)low[u]=min(low[u],dfn[v]);
}
}
vector<ll>es[N];
void dfs2(ll x,ll c){
bel[x]=c,sc[c]++;
for(ll i=hd[x];i;i=E[i].nxt){
ll y=E[i].to;
if(cut[i]||bel[y])continue;
dfs2(y,c);
}
}
void dfs(ll x,ll fa){
dp[x][sc[x]]=1;
sz[x]=sc[x];
for(ll y:es[x]){
if(y==fa)continue;
dfs(y,x);
rep(i,1,sz[x]+sz[y])tmp[i]=0;
rep(i,1,sz[x]){
rep(j,1,sz[y])tmp[i+j]+=dp[x][i]*dp[y][j]*pw2[i*j-1];
rep(j,1,sz[y])tmp[i]-=dp[x][i]*dp[y][j];
}
sz[x]+=sz[y];
rep(i,1,sz[x])dp[x][i]=tmp[i];
}
}
bool Med;
int main(){
cerr<<fabs(&Med-&Mbe)/1048576.0<<"MB\n";
n=read(),m=read();
rep(i,1,m){
ll x=read(),y=read();
adde(x,y),adde(y,x);
}
tarjan(1,0);
rep(i,1,n){
if(!bel[i])cnt++,dfs2(i,cnt);
}
rep(i,1,n){
for(ll j=hd[i];j;j=E[j].nxt){
if(bel[i]!=bel[E[j].to])es[bel[i]].push_back(bel[E[j].to]);
else esc[bel[i]]++;
}
}
rep(i,1,cnt)esc[i]>>=1;
pw2[0]=1;
rep(i,1,n*n)pw2[i]=pw2[i-1]*2;
mint coef=1;
rep(i,1,cnt)coef*=pw2[sc[i]*(sc[i]-1)/2-esc[i]];
dfs(1,0);
mint ans=0;
rep(i,0,n)ans+=dp[1][i];
write((ans*coef).val());
return 0;
}