#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
const int M=1e6+5;
const int mod=1e9+7;
const int inv2=(mod+1)/2;

vector<int>e[N],t[N];
bool vis[N];
int n,m,dfn[N],low[N],cntdfn=0,st[N],top=0,col[N],cntcol=0,siz[N];
void tarjan(int now,int father) {
	low[now]=dfn[now]=++cntdfn;
	vis[st[++top]=now]=1;
	for (int to:e[now]) {
		if (to==father) {
			continue;
		}
		if (!dfn[to]) {
			tarjan(to,now);
			low[now]=min(low[now],low[to]);
		} else if (vis[to]) {
			low[now]=min(low[now],dfn[to]);
		}
	}
	if (low[now]==dfn[now]) {
		int x,c=++cntcol;
		do {
			x=st[top--];
			col[x]=c;
			vis[x]=0;
			siz[c]++;
		}while (x!=now);
	}
}
int f[N][3],pw[M];
void dfs(int now,int father) {
	f[now][0]=1,f[now][1]=0,f[now][2]=pw[siz[now]]-1;
	for (int to:t[now]) {
		if (to==father) {
			continue;
		}
		dfs(to,now);
		int g[3]={};
		for (int x=0;x<=2;x++) {
			for (int y=0;y<=2;y++) {
				int w=y?inv2:1;
				g[min(x+min(y,1),2)]=(g[min(x+min(y,1),2)]+1LL*f[now][x]*f[to][y]%mod*w)%mod;
			}
		}
		memcpy(f[now],g,sizeof(g));
	}
}

signed main() {
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	
	ios::sync_with_stdio(false),cin.tie(0);
	cout.precision(10),cout.setf(ios::fixed);
	
	cin>>n>>m;
	for (int i=pw[0]=1;i<=m;i++) {
		pw[i]=pw[i-1]*2%mod;
		int u,v;
		cin>>u>>v;
		e[u].emplace_back(v);
		e[v].emplace_back(u);
	}
	tarjan(1,0);
	for (int i=1;i<=n;i++) {
		for (int j:e[i]) {
			if (col[i]!=col[j]) {
				t[col[i]].emplace_back(col[j]);
			}
		}
	}
	dfs(1,0);
	int ans=0;
	for (int i=1;i<=n;i++) {
		ans=(ans+f[i][2])%mod;
	}
	ans=1LL*ans*pw[m]%mod;
	cout<<ans<<"\n";
	
	return 0;
}
