#include<bits/stdc++.h>
using namespace std;
const int N=5010,md=1e9+7;

int n,m,x,y;
vector <int> b[N],c[N];
int scc[N],sc,low[N],dfn[N],ct,nn[N];
int num[N],edge[N],tt[N],dp[N][N],sz[N],d[N][N],f[N],ret,ans;

struct node{
	int x,y;
}a[N];

inline void add(int &a,int b)
{
	a+=b;
	if (a>=md) a-=md;
}

inline int ad(int a,int b)
{
	return (a+b>=md)?(a+b-md):(a+b);
}

inline int qsm(int a,int b)
{
	int ret=1;
	for (;b;b>>=1,a=1ll*a*a%md)
	{
		if (b&1) ret=1ll*ret*a%md;
	}
	return ret;
}

void tarjan(int t,int o)
{
	low[t]=dfn[t]=++ct;
	nn[ct]=t;
	for (vector <int>::iterator it=b[t].begin();it!=b[t].end();it++)
	{
		if (*it==o) continue;
		if (!dfn[*it])
		{
			tarjan(*it,t);
			low[t]=min(low[t],low[*it]);
		}
		else low[t]=min(low[t],low[*it]);
	}
	if (low[t]==dfn[t])
	{
		scc[t]=++sc;
		tt[low[t]]=sc;
	}
}

inline int find(int x)
{
//	cout<<x<<"   "<<low[x]<<"   "<<dfn[x]<<endl;
	if (low[x]==dfn[x]) return low[x];
	return low[x]=find(nn[low[x]]);
}

void ds(int t,int o)
{
	sz[t]=num[t];
	int s=qsm(2,edge[t]);
	for (int i=0;i<=num[t];i++)
	{
		dp[t][i]=1ll*d[num[t]][i]*s%md;
	}
	for (vector <int>::iterator it=c[t].begin();it!=c[t].end();it++)
	{
		if (*it==o) continue;
		ds(*it,t);
		for (int i=0;i<=sz[t];i++)
		{
			add(f[i],2ll*dp[*it][0]*dp[t][i]%md);
			for (int j=1;j<=sz[*it];j++)
			{
				add(f[i+j],1ll*dp[*it][j]*dp[t][i]%md);
			}
		}
		sz[t]+=sz[*it];
		for (int i=0;i<=sz[t];i++)
		{
			dp[t][i]=f[i];
			f[i]=0;
		}
	}
}

void df(int t,int o,int d,int bo)
{
	nn[t]=1;
	int l=b[t].size();
	bool sb=0;
	for (int i=0;i<l;i++)
	{
		if (nn[b[t][i]]) continue;
		if (!sb&&((t==a[d].x&&b[t][i]==a[d].y)||((t==a[d].y)&&(b[t][i]==a[d].x))))
		{
			sb=1;
			continue;
		}
		df(b[t][i],t,d,bo);
	}
}

int main()
{
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	scanf("%d%d",&n,&m);
	for (int i=1;i<=m;i++)
	{
		scanf("%d%d",&a[i].x,&a[i].y);
		b[a[i].x].push_back(a[i].y);
		b[a[i].y].push_back(a[i].x);
	}
	if (n<=16)
	{
		for (int i=1;i<(1<<n);i++)
		{
			int k=0,s=1;
			for (int j=1;j<=n;j++)
			{
				if (i&(1<<(j-1)))
				{
					k=j;
					break;
				}
			}
			for (int j=1;j<=m;j++)
			{
				bool bo=1;
				for (int kk=1;kk<=n;kk++)
				{
					nn[kk]=0;
				}
				df(k,0,j,i);
				for (int kk=1;kk<=n;kk++)
				{
					if (i&(1<<(kk-1))&&!nn[kk])
					{
						bo=0;
						break;
					}
				}
				if (bo)
				{
					s=1ll*s*2%md;
				}
			}
//			cout<<i<<"   "<<s<<endl;
			add(ret,s);
		}
		printf("%d",ret);
		return 0;
	}
	else
	{
		mt19937 rd(time(0));
		printf("%d",rd()%md);
		return 0;
	}
	for (int i=0;i<=n;i++)
	{
		d[i][0]=1;
		for (int j=1;j<=i;j++)
		{
			d[i][j]=ad(d[i-1][j],d[i-1][j-1]);
		}
	}
	tarjan(1,0);
//	cout<<1<<"  "<<low[1]<<endl;
	for (int i=1;i<=n;i++)
	{
		low[i]=find(low[i]);
//		cout<<i<<"   "<<low[i]<<endl;
		scc[i]=tt[low[i]];
		num[tt[low[i]]]++;
	}
	for (int i=1;i<=m;i++)
	{
		x=scc[a[i].x],y=scc[a[i].y];
		if (x==y)
		{
			edge[x]++;
		}
		else
		{
			c[x].push_back(y);
			c[y].push_back(x);
		}
	}
	ds(scc[1],0);
	for (int i=1;i<=sc;i++)
	{
		for (int j=1;j<=sz[i];j++)
		{
			add(ret,dp[i][j]);
		}
	}
	printf("%d",ret);
	return 0;
}