#include<cstdio>
#include<iostream>
#include<stack>
#define MAXM 2000005
#define MAXN 500005
#define p 1000000007
#define ll long long
using namespace std;
stack<int> stk;
int nn,b[MAXN],c[MAXN],vet[MAXM],nxt[MAXM],head[MAXN],tot,vet1[MAXM],nxt1[MAXM],head1[MAXN],tot1,
u,v,n,m,low[MAXN],dfn[MAXN],is_stk[MAXN];
ll dp[MAXN][3];
void addedge(int u, int v) {
	vet[++tot]=v;
	nxt[tot]=head[u];
	head[u]=tot;
}
void addedge1(int u, int v) {
	vet1[++tot1]=v;
	nxt1[tot1]=head1[u];
	head1[u]=tot1;
}
void tarjan(int now, int t, int fa) {
	dfn[now]=low[now]=t;
	is_stk[now]=1;
	stk.push(now);
	for (int i=head[now]; i; i=nxt[i]) {
		int v=vet[i];
		if (v!=fa) {
			if (!dfn[v]) {
				tarjan(v,t+1,now);
				if (is_stk[v]) low[now]=min(low[v],low[now]);
			}	
			else if (is_stk[v]) low[now]=min(low[v],dfn[now]);
		}	
	} 
	if (low[now]==dfn[now]) {
		int h=stk.top();
		++nn;
		c[low[now]]=nn;
		while (stk.size() && low[h]==low[now]) {
			b[nn]++;
			is_stk[h]=0;                           
			stk.pop();	
			if (stk.size()) h=stk.top();
		}
	}
}
void dfs(int u, int fa) {
	for (int i=head[u]; i; i=nxt[i]) {
		int v=vet[i];
		if (v!=fa) {
			if (low[u]!=low[v]) {
				addedge1(c[low[u]],c[low[v]]);
				addedge1(c[low[v]],c[low[u]]);
			}
			dfs(v,u);
		}
	}
}
ll qpow(int a) {
	ll res=1,t=2;
	while (a) {
		if (a & 1) res=res*t % p;
		a=a >> 1;
		t=t*t % p;
	}
	return res;
}
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", &u, &v);
		addedge(u,v);
		addedge(v,u);
	}
	tarjan(1,1,0);
	dfs(1,0);
	ll ans=1;
	for (int i=1; i<=nn; i++) 
		b[i]=qpow(b[i]);
	for (int i=1; i<=nn; i++) 
		ans=ans*(b[i]+1) % p;
	ans-=1;
	b[0]=1;
	addedge1(0,1);
	addedge1(0,1);
	//dfs1(0,-1);
	//printf("%lld", dp[0][0]);
	printf("%lld", (ans-qpow(nn)+1+p) % p * qpow(m-nn+1) % p);
	return 0;
}