#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mo=1e9+7;
const int N=500005,M=2000005;
ll fpow(ll a,ll b=mo-2){ll res=1;for(;b;b>>=1,a=a*a%mo)if(b&1)res=res*a%mo;return res;}
int en,hd[N],nx[M],to[M];
void add(int u,int v){
	nx[++en]=hd[u];
	hd[u]=en;
	to[en]=v;
}
int dfn[N],low[N],st[N],top,dn;
int cn,col[N];
ll sz[N],sz2[N],t[N];
void dfs(int u,int fa){
	dfn[u]=low[u]=++dn;
	st[++top]=u;
	for(int i=hd[u];i;i=nx[i]){
		int v=to[i];
		if(v==fa)continue;
		if(!dfn[v]){
			dfs(v,u);
			low[u]=min(low[u],low[v]);
		}else if(!col[v])low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]){
		cn++;
		do{
			col[st[top]]=cn;
			sz[cn]++;
		}while(u!=st[top--]);
	}
}
int n,m,U[M],V[M];
vector<int>g[N];
ll f[N][3];
void DFS(int u,int fa){
	ll w=1,w2=1;
	for(auto v:g[u]){
		if(v==fa)continue;
//		printf("%d->%d\n",u,v);
		DFS(v,u);
		t[u]+=t[v]+1;
		w=(f[v][0]+f[v][1]+2*f[v][2])%mo*w%mo;
		w2=w2*2*f[v][2]%mo;
	}
	f[u][0]=sz2[u]*(w-w2+mo)%mo;
	f[u][1]=(sz[u]-1+mo)*sz2[u]%mo*w%mo;
	f[u][2]=sz2[u]*w2%mo;
//	printf("|%d:%lld,%lld,(%lld,%lld)%lld %lld %lld|\n",u,w,w2,sz[u],sz2[u],f[u][0],f[u][1],f[u][2]);
}
int main(){
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&U[i],&V[i]);
//		if(U[i]>V[i])swap(U[i],V[i]);
		add(U[i],V[i]),add(V[i],U[i]);
	}
	dfs(1,0);
//	for(int i=1;i<=n;i++)printf("%d:%d\n",i,col[i]);
	for(int i=1;i<=m;i++){
		if(col[U[i]]==col[V[i]])sz2[col[U[i]]]++;
		else g[col[U[i]]].push_back(col[V[i]]),g[col[V[i]]].push_back(col[U[i]]);
	}
	for(int i=1;i<=cn;i++){
		sz[i]=fpow(2,sz[i]);
		t[i]=sz2[i];
		sz2[i]=fpow(2,sz2[i]);
//		printf("%lld %lld\n",sz[i],sz2[i]);
	}
	DFS(1,0);
//	for(int i=1;i<=cn;i++)
//		printf("|%d:%lld %lld %lld|\n",i,f[i][0],f[i][1],f[i][2]);
	ll ans=0;
	for(int i=1;i<=cn;i++)
		(ans+=f[i][1]*fpow(2,m-t[i]))%=mo;
	printf("%lld\n",ans);
	return 0;
}