#include<bits/stdc++.h>
using namespace std;
const long long P=1000000007;
inline int mo(long long x){return x<P?x:x-P;}
struct G{
	int edgenum,head[500005],nxt[2000005],vet[2000005];
	G(){edgenum=1;}
	void addedge(int u,int v){
		edgenum++;
		nxt[edgenum]=head[u];
		head[u]=edgenum;
		vet[edgenum]=v;
	}
}g1,g2;
int fa1[500005],up[500005],dep[500005],to[500005],vnum,fe[500005];
bool vis[500005];
int n,fa2[500005],s[500005],vn[500005];
long long f[500005][2],ff[500005],mi[500005];
void dfs1(int u){
	up[u]=u;
	vis[u]=true;
	for(int e=g1.head[u];e;e=g1.nxt[e]){
		int v=g1.vet[e];
		if(!vis[v]){
			dep[v]=dep[u]+1;
			fa1[v]=u;
			fe[v]=e^1;
			dfs1(v);
		}
		if(e!=fe[u] && dep[up[v]]<dep[up[u]])
			up[u]=up[v];
	}
	if(up[u]==u) to[u]=++vnum;
}
void dfs1_5(int u){
	for(int e=g1.head[u];e;e=g1.nxt[e]){
		int v=g1.vet[e];
		if(fa1[v]!=u) continue;
		if(!to[v]) to[v]=to[u];
		dfs1_5(v);
	}
}
void dfs2(int u){
	s[u]=1,f[u][1]=mi[vn[u]]-1,f[u][0]=1,ff[u]=1;
	for(int e=g2.head[u];e;e=g2.nxt[e]){
		int v=g2.vet[e];
		dfs2(v);
		s[u]+=s[v];
		f[u][1]=f[u][1]*(ff[v]+mi[s[v]])%P;
		f[u][0]=f[u][0]*(ff[v]+mi[s[v]])%P;
		ff[u]=ff[u]*(ff[v]+1)%P;
	}
	long long sum1=0,sum2=0;
	for(int e=g2.head[u];e;e=g2.nxt[e]){
		int v=g2.vet[e];
		sum1=(sum1+(f[v][0]+f[v][1])*mi[s[u]-s[v]])%P;
		sum2=(sum2+ff[v]*mi[s[u]-s[v]-1])%P;
	}
	f[u][0]=mo((f[u][0]+sum1-sum2-mi[s[u]-1])%P+P);
	ff[u]=mo(mo(ff[u]+f[u][1]-1+P));
}
int main(){
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	int m;
	scanf("%d%d",&n,&m);
	mi[0]=1;
	for(int i=1;i<=n;i++)
		mi[i]=mo(mi[i-1]<<1);
	while(m--){
		int u,v;
		scanf("%d%d",&u,&v);
		g1.addedge(u,v);
		g1.addedge(v,u);
	}
	dfs1(1);
	dfs1_5(1);
	int x=0;
	for(int i=1;i<=n;i++){
		vn[to[i]]++;
		for(int e=g1.head[i];e;e=g1.nxt[e]){
			int v=g1.vet[e];
			if(to[v]==to[i]) x++;
			else if(to[v]<to[i]) g2.addedge(to[i],to[v]);
		}
	}
	dfs2(vnum);
//	for(int i=1;i<=vnum;i++)
//		printf("%d %d %d %d\n",i,f[i][0],f[i][1],ff[i]);
	printf("%lld",(f[vnum][0]+f[vnum][1])*mi[x>>1]%P);
	return 0;
}