#include<bits/stdc++.h>
using namespace std;
constexpr int N=500000,M=1000000,mod=1e9+7;
inline void reduce(int &x){if(x>=mod) x-=mod;}
inline void reduce_(int &x){x+=x>>31&mod;}
inline void reduce2(int &x){if(x&1) x+=mod;x>>=1;}
int p2[M+10];
void initp(int n){
	p2[0]=1;
	int i;
	for(i=1;i<=n;++i) reduce(p2[i]=p2[i-1]<<1);
}
inline void down(int &x,int y){if(y<x) x=y;}
struct EDGE{
	int to,next;
}e[(M<<1)+10];
int head[N+10],etop;
void adde(int u,int v){
	e[etop].to=v;
	e[etop].next=head[u];
	head[u]=etop++;
}
int low[N+10],dfn[N+10],clk,vis[N+10],col[N+10],ctop,cfa[N+10],ccnt[N+10];
deque<int> q;
void dfs(int x,int efa){
	dfn[x]=low[x]=++clk;
	vis[x]=1;
	q.push_back(x);
	int i;
	for(i=head[x];~i;i=e[i].next){
		if(i==efa) continue;
		if(vis[e[i].to]==2) continue;
		if(!vis[e[i].to]){
			dfs(e[i].to,i^1);
			down(low[x],low[e[i].to]);
			if(low[e[i].to]>dfn[x]) cfa[col[e[i].to]]=x;
		}
		else down(low[x],dfn[e[i].to]);
	}
	if(dfn[x]==low[x]){
		int tmp;
		++ctop;
		while(!q.empty()){
			tmp=q.back();
			q.pop_back();
			col[tmp]=ctop;
			++ccnt[ctop];
			vis[tmp]=2;
			if(tmp==x) break;
		}
	}
}
int f[N+10],g[N+10];
void dfs1(int x){
	int i,mul=p2[ccnt[x]];
	for(i=head[x];~i;i=e[i].next){
		dfs1(e[i].to);
		int tmp=f[e[i].to];
		reduce2(tmp);
		reduce(++tmp);
		mul=(long long)mul*tmp%mod;
	}
	reduce_(f[x]=mul-1);
	g[x]=f[x];
	for(i=head[x];~i;i=e[i].next){
		int tmp=f[e[i].to];
		reduce2(tmp);
		reduce_(g[x]-=tmp);
	}
}
int main(){
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	initp(M);
	memset(head,255,sizeof(head));
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n,m;
	cin>>n>>m;
	int i;
	for(i=1;i<=m;++i){
		int u,v;
		cin>>u>>v;
		adde(u,v);
		adde(v,u);
	}
	dfs(1,-1);
	for(i=1;i<ctop;++i) cfa[i]=col[cfa[i]];
	etop=0;
	memset(head,255,sizeof(head));
	for(i=1;i<ctop;++i) adde(cfa[i],i);
	dfs1(ctop);
	int ans=0;
	for(i=1;i<=ctop;++i) reduce(ans+=g[i]);
	cout<<(long long)ans*p2[m]%mod<<'\n';
	return 0;
}
