#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

ll read()
{
	ull n=0; ll f=1; char ch=getchar();
	for(;ch<'0'||'9'<ch;ch=getchar()) if(ch=='-') f=-1;
	for(;'0'<=ch&&ch<='9';ch=getchar()) n=(n<<3)+(n<<1)+(ch^48);
	return f*n;
}

const int N=2e6+5;
const int p=1e9+7;
inline ll qpow(int a,int b)/*a^b*/{ll ans=1;for(;b;b>>=1){if(b&1) ans=ans*a%p;a=a*a%p;}return ans;}
ll fac[N];
inline void initfac(){fac[0]=1;for(int i=1;i<=(int)2e6;i++) fac[i]=fac[i-1]*i%p;}
int n,m;
int V[N],H[N],K[N],l=1;
inline void Add(int x,int y){V[++l]=y,K[l]=H[x],H[x]=l;}
int V0[N],H0[N],K0[N],l0=1;
inline void Add0(int x,int y){V0[++l0]=y,K0[l0]=H0[x],H0[x]=l0;}
inline void add0(int u,int v){Add0(u,v),Add0(v,u);}

ll dp[N][2];
//dp[u][0] dian buqu shi fanganshu
//dp[u][1] dian   qu shi fanganshu

namespace sub1
{
void dfs(int x,int fa)
{
	dp[x][0]=dp[x][1]=1;
	for(int i=H0[x];i;i=K0[i])
	{
		int y=V0[i];
		if(y==fa) continue;
		dfs(y,x);
		dp[x][0]=dp[x][0]*((dp[y][0]+dp[y][1]+2)%p)%p;
		dp[x][1]=dp[x][1]*((dp[y][0]+dp[y][1]+1)%p)%p;
	}
	//printf("x=%d 0-%d 1-%d\n",x,dp[x][0],dp[x][1]);
}

inline void calc_sum()
{
	dfs(1,-1);
	ll ans=((dp[1][0]+dp[1][1])%p+(p-qpow(2,m))%p)%p;
	printf("%lld\n",ans);
}
}

namespace sub2
{
int dfn[N],low[N],t=0;
int st[N],top=0;
int blg[N];//blg-belong
vector<int> cntv; int cnt=0;
vector<int> cnte;
void tarjan(int x,int fa)
{
	low[x]=dfn[x]=++t, st[++top]=x;
	for(int i=H[x];i;i=K[i])
	{
		int y=V[i];
		//printf("x=%d y=%d i=%d\n",x,y,i);
		if(y==fa) continue;
		if(!dfn[y]) 
		{
			tarjan(y,x);
			low[x]=min(low[x],low[y]);
		}
		else
			low[x]=min(low[x],dfn[y]);
		//printf("x=%d y=%d low[y]=%d\n",x,y,low[x]);
	}
	if(low[x]>=dfn[x])
	{
		//printf("! x=%d\n",x);
		cntv.push_back(0);cnte.push_back(0); ++cnt;
		for(;st[top]!=x;--top)
		{
			blg[st[top]]=cnt, ++cntv[cnt];
		}
		blg[x]=cnt, ++cntv[cnt];
		--top;
	}
}

int fa[N];
inline void init(){for(int i=1;i<=cnt;i++) fa[i]=i;}
int Find(int x){return fa[x]==x?x:fa[x]=Find(fa[x]);}
inline void Union(int x,int y)
{
	x=Find(x),y=Find(y);
	if(x==y) return;
	fa[y]=x;
}

int q[N],hd,tl;
int vi[N];
inline void bfs()
{
	hd=1,tl=0;
	for(q[++tl]=1;hd<=tl;)
	{
		int x=q[hd++];
		//printf("%d %d\n",x,blg[x]);
		if(vi[x]) continue;
		vi[x]=1;
		for(int i=H[x];i;i=K[i])
		{
			int y=V[i];
			//printf("\t%d %d\n",y,blg[y]);
			if(blg[x]==blg[y]) ++cnte[blg[x]];
			else
			{
				int u=Find(blg[x]),v=Find(blg[y]);
				//printf("\tu=%d v=%d\n",u,v);
				if(u!=v) add0(u,v),Union(u,v);//,printf("add %d %d\n",u,v)
			}
			if(!vi[y]) q[++tl]=y;
		}
	}
}

void dfs(int x,int fa)
{
	dp[x][0]=(qpow(2,cntv[x])-1)%p*qpow(2,cnte[x])%p;
	dp[x][1]=qpow(2,cnte[x])%p;
	for(int i=H0[x];i;i=K0[i])
	{
		int y=V0[i];
		if(y==fa) continue;
		dfs(y,x);
		dp[x][0]=dp[x][0]*((dp[y][0]+dp[y][1]+2)%p)%p;
		dp[x][1]=dp[x][1]*((dp[y][0]+dp[y][1]+1)%p)%p;
	}
	//printf("x=%d 0-%d 1-%d\n",x,dp[x][0],dp[x][1]);
}


inline void calc_sum()
{
	cntv.push_back(0),cnte.push_back(0);
	tarjan(1,0);
	//for(int i=1;i<=cnt;i++)
	//	printf("%d %d\n",i,cntv[i]);
	init();
	bfs();
	for(int i=1;i<=cnt;i++)
	{
		cnte[i]>>=1;
		//printf("e %d %d\n",i,cnte[i]);
	}
	dfs(1,-1);
	ll ans=(dp[1][0]+dp[1][1])%p;
	ans=(ans-qpow(2,m)+p)%p;
	printf("%lld\n",ans);
}
}

void Solve()
{
	n=read(),m=read();
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		Add(u,v),Add(v,u);
		if(m==n-1) add0(u,v);
	}
	if(m==n-1) sub1::calc_sum();
	else
		sub2::calc_sum();
}

#define FILESIO 2
int main()
{
  #ifdef FILESIO
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
  #endif
    
    int T=1;
    //initfac();
    //scanf("%d",&T);
    for(;T--;)
    {
    	Solve();
	}
  
  #ifdef FILESIO
	fclose(stdin);
	fclose(stdout);
  #endif
    return 0;
}

