#include<bits/stdc++.h>
#define Cn const
#define CI Cn int&
#define N 500000
#define M 1000000
#define X 1000000007
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
using namespace std;
namespace FastIO
{
	#define FS 100000
	#define tc() (FA==FB&&(FB=(FA=FI)+fread(FI,1,FS,stdin),FA==FB)?EOF:*FA++)
	char oc,FI[FS],*FA=FI,*FB=FI;
	void read(int& x) {x=0;while(!isdigit(oc=tc()));while(x=(x<<3)+(x<<1)+(oc&15),isdigit(oc=tc()));}
}using namespace FastIO;
int n,m,pw[M+5],ee=1,lnk[N+5];struct edge {int to,nxt,g;}e[2*M+5];
int d,dfn[N+5],low[N+5];void Tarjan(int x,int lst=0)
{
	dfn[x]=low[x]=++d;for(int i=lnk[x],y;i;i=e[i].nxt) if((y=e[i].to)^lst)
	{
		if(dfn[y]) {low[x]=min(low[x],dfn[y]);continue;}
		if(Tarjan(y,x),low[y]<=dfn[x]) {low[x]=min(low[x],low[y]);continue;}e[i].g=e[i^1].g=1;
	}
}
int ct,c[N+5],bl[N+5];void Mark(int x)
{
	++c[bl[x]=ct];for(int i=lnk[x];i;i=e[i].nxt) !e[i].g&&!bl[e[i].to]&&(Mark(e[i].to),0);
}
namespace T
{
	int ee,lnk[N+5];struct edge {int to,nxt;}e[2*N+5];void Add(int x,int y) {add(x,y),add(y,x);}
	int ans,f[N+5],s[N+5];void DP(int x,int lst=0)
	{
		f[x]=pw[c[x]]-1,s[x]=1;for(int i=lnk[x],y,f_;i;i=e[i].nxt) if((y=e[i].to)^lst)
		{
			DP(y,x),f_=(1LL*f[x]*f[y]+1LL*f[x]*pw[s[y]]+1LL*pw[s[x]-1]*f[y])%X,f[x]=f_,s[x]+=s[y];
		}
		ans=(ans+1LL*f[x]*(x^1?pw[ct-1-s[x]]:1))%X;
	}
	void Solve() {DP(1),printf("%d\n",(int)(1LL*ans*pw[m-(ct-1)]%X));}
}
int main()
{
	freopen("barrack.in","r",stdin),freopen("barrack.out","w",stdout);
	int i,x,y;for(read(n),read(m),i=1;i<=m;++i) read(x),read(y),add(x,y),add(y,x);
	for(pw[0]=i=1;i<=max(n,m);++i) pw[i]=(pw[i-1]<<1)%X;
	for(Tarjan(1),i=1;i<=n;++i) !bl[i]&&(++ct,Mark(i),0);
	for(i=1;i<=m;++i) e[i<<1].g&&(T::Add(bl[e[i<<1].to],bl[e[i<<1|1].to]),0);return T::Solve(),0;
}
