#include<bits/stdc++.h>
#define Max(x,y) ((x<y)&&(x=y))
#define Min(x,y) ((x>y)&&(x=y))
using namespace std;

typedef long long ll;
const ll P=1e9+7;
const int M=5e5+5,N=1e6+5;

inline int read()
{
	int x=0,f=1;static char ch;
	while(ch=getchar(),ch<48)if(ch==45)f=0;
	do x=(x<<1)+(x<<3)+(ch^48);
	while(ch=getchar(),ch>=48);
	return f?x:-x;
}

int n,m,u[M],v[M];

void ADD(ll &x,ll y){(x+=y)>=P?x-=P:x;}
ll Pw[M];

int fa[M];
int find(int x)
{
	if(fa[x]!=x)fa[x]=find(fa[x]);
	return fa[x];
}
bool tag[N];

void Find_bridge()
{
	for(int z=1;z<=m;z++)
	{
		for(int i=1;i<=n;i++)fa[i]=i;
		for(int i=1,x,y;i<=m;i++)
		{
			if(i==z)continue;
			x=find(u[i]),y=find(v[i]);
			if(x!=y)fa[x]=y;
		}
		int cnt=0;
		for(int i=1;i<=n;i++)
			if(find(i)==i)cnt++;
		if(cnt>1)tag[z]=true;
	}
//	for(int z=1;z<=m;z++)
//		if(tag[z])printf("%d ",z);
//	printf("\n");
}

namespace P35
{
	int siz[100],cnt;
	int a[100],b[100],sum[100];
	int anc[100];ll ans,tmp;
	
	void solve()
	{
		for(int i=1;i<=n;i++)
			fa[i]=i,siz[i]=1;
		for(int z=1,x,y;z<=m;z++)
		{
			if(tag[z])continue;
			x=find(u[z]),y=find(v[z]);
			if(x!=y)fa[y]=x,siz[x]+=siz[y];
		}
		for(int i=1;i<=n;i++)anc[i]=find(i);
		for(int z=1;z<=m;z++)
			if(tag[z])
			{
				cnt++;
				a[cnt]=anc[u[z]];
				b[cnt]=anc[v[z]];
			}
		for(int st=0;st<(1<<cnt);st++)
		{
			for(int i=1;i<=n;i++)
				fa[i]=anc[i],sum[i]=siz[i];
			for(int i=1,x,y;i<=cnt;i++)
				if(st&(1<<i-1))
				{
					x=find(a[i]),y=find(b[i]);
					fa[y]=x,sum[x]+=sum[y];
				}
			for(int i=1;i<=n;i++)
				if(find(i)==i)
				{
					tmp=(Pw[sum[i]]-1)%P;
					ADD(ans,tmp);
				}
		}
		ans=ans*Pw[m-cnt]%P;
		printf("%lld",ans);
	}
}

int main()
{
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	
	n=read(),m=read();
	for(int i=1;i<=m;i++)
		u[i]=read(),v[i]=read();
	Pw[0]=1ll;
	for(int i=1;i<=n;i++)
		Pw[i]=(Pw[i-1]<<1ll)%P;
	
	if(n<=3000&&m<=5000)Find_bridge();
	
	if(n<=16&&m<=25)P35::solve();
	else ;
	
	return 0;
}
