#include<bits/stdc++.h>
#define I inline
#define RI register int
#define rep(i,a,b) for(RI i=a;i<=b;++i)
#define dow(i,a,b) for(RI i=a;i>=b;--i)
#define edg(i,u,v) for(RI v,i=head[u];v=e[i].to,i;i=e[i].next)
using namespace std;
const int N=2e6+5,mo=1e9+7;
I int add(int a,int b){return a+b>=mo?a+b-mo:a+b; }
I int sub(int a,int b){ return a-b<0?a-b+mo:a-b; }
I int mul(int a,int b){ return 1ll*a*b%mo; }
I int fast(int a,int b=mo-2){
	RI res=1;while(b) b&1&&(res=mul(res,a)),a=mul(a,a),b>>=1;return res; }
struct edge{ int to,next,w;} e[N<<1];
int n,m,tot,fa[N],from[N],to[N],dp[N][2],siz[N],dfn[N],vis[N],low[N],cnt=1,sz[N],x,y,head[N];
I void add_e(int from,int to){ e[++cnt]=(edge){ to,head[from],0},head[from]=cnt; }
I void add_e(int from,int to,int w){ e[++cnt]=(edge){ to,head[from],w},head[from]=cnt; }
I void tarjan(int u,int f){
	dfn[u]=low[u]=++tot;
	edg(i,u,v) if(v^f){
		if(!dfn[v]){
			tarjan(v,u),low[u]=min(low[u],low[v]);
			if(low[v]==dfn[v]) e[i].w=e[i^1].w=1;
		}
		else low[u]=min(low[u],dfn[v]);
	}
}
I void dfs(int u,int f,int col){ sz[col+n]++,vis[u]=col;edg(i,u,v) if(!e[i].w&&!vis[v]) dfs(v,u,col); }
I void dfs2(int u,int f,int x){
	dp[u][0]=fast(2,siz[u]),dp[u][1]=sub(fast(2,sz[u]),1);
	edg(i,u,v) if(v^f){
		dfs2(v,u,e[i].w);
		dp[u][1]=mul(dp[u][1],add(add(dp[v][0],dp[v][0]),dp[v][1]));
		dp[u][0]=mul(dp[u][0],mul(2,add(dp[v][0],dp[v][1])));
	}
}
I int find(int u){ return u==fa[u]?u:fa[u]=find(fa[u]); }
I void merge(int x,int y){
	x=find(x),y=find(y),x^y&&(fa[x]=y,sz[y]+=sz[x]);
}
int main(){
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	scanf("%d%d",&n,&m);
	rep(i,1,m) scanf("%d%d",&x,&y),add_e(x,y),add_e(y,x);
	tarjan(1,0),tot=0;
	rep(i,1,n) if(!vis[i]) dfs(i,0,++tot);
	rep(u,1,n) edg(i,u,v) if(u<v) {	
		if(vis[v]^vis[u]) add_e(vis[u]+n,vis[v]+n,v),add_e(vis[v]+n,vis[u]+n,u);
		else siz[vis[u]+n]++,sz[vis[u]+n]++;
	}
	dfs2(n+1,0,1);
	return printf("%d\n",sub(add(dp[n+1][0],dp[n+1][1]),fast(2,m))),0;
}