// Author:A weak man named EricQian
// Attention:Check your code while coding
// 100 pts
#include<bits/stdc++.h>
using namespace std;
#define infll 0x3f3f3f3f3f3f3f3fll
#define inf 0x3f3f3f3f
#define pb push_back
#define eb emplace_back
#define pa pair<int,int>
#define fi first
#define se second
#define all(x) ((x).bgein(),(x).end())
typedef long long ll;
#define Maxn 500005
#define Maxm 1000005
#define mod 1000000007
inline int rd()
{
	int x=0;
	char ch,t=0;
	while(!isdigit(ch = getchar())) t|=ch=='-';
	while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
	return t?-x:x;
}
int n,m,tot=1,Time,sum,muti=1;
int hea[Maxn],nex[Maxm<<1],ver[Maxm<<1];
int dfn[Maxn],low[Maxn],bel[Maxn],pow2[Maxm];
int dp[Maxn][3],pre[Maxn][2],suf[Maxn][2],son[Maxn],siz[Maxn],hav[Maxn];
vector<int> g[Maxn]; // Finish tarjan
bool isge[Maxm<<1],vis[Maxn];
inline void add(int x,int y){ ver[++tot]=y,nex[tot]=hea[x],hea[x]=tot; }
void tarjan(int x,int Lastedge)
{
	dfn[x]=low[x]=++Time;
	for(int i=hea[x];i;i=nex[i])
	{
		if(!dfn[ver[i]])
		{
			tarjan(ver[i],i),low[x]=min(low[x],low[ver[i]]);
			if(low[ver[i]]>dfn[x]) isge[i]=isge[i^1]=true;
		}
		else if(i!=(Lastedge^1)) low[x]=min(low[x],dfn[ver[i]]);
	}
}
void Find(int x)
{
	vis[x]=true,bel[x]=sum,hav[sum]++;
	for(int i=hea[x];i;i=nex[i]) if(!isge[i] && !vis[ver[i]]) Find(ver[i]);
}
inline int Chose(int x) { return (pow2[hav[x]]-1+mod)%mod; }
void solve(int x,int fa)
{
	siz[x]=1;
	for(int v:g[x]) if(v!=fa) solve(v,x),siz[x]+=siz[v];
	int cnt=0;
	for(int v:g[x]) if(v!=fa) son[++cnt]=v;
	for(int i=0;i<=cnt+1;i++) pre[i][0]=pre[i][1]=suf[i][0]=suf[i][1]=0;
	pre[0][0]=suf[cnt+1][0]=1;
	for(int i=1;i<=cnt;i++)
	{
		pre[i][0]=2ll*pre[i-1][0]%mod*pow2[siz[son[i]]-1]%mod;
		pre[i][1]=(
			1ll*pre[i-1][0]*dp[son[i]][1]+
			1ll*pre[i-1][1]*(dp[son[i]][1]+pow2[siz[son[i]]-1]*2ll%mod)%mod
			)%mod;
	}
	for(int i=cnt;i>=1;i--)
		suf[i][0]=2ll*suf[i+1][0]%mod*pow2[siz[son[i]]-1]%mod;
	int tmp=1ll*Chose(x)*pow2[siz[x]-1]%mod;
	dp[x][1]=(dp[x][1]+tmp)%mod;
	dp[x][2]=(dp[x][2]+tmp)%mod;
	for(int i=1;i<=cnt;i++)
	{
		// 1.1
		tmp=(1ll*(Chose(x)+1ll)*(pre[i-1][0]+pre[i-1][1])%mod+mod-pre[i-1][0])%mod*suf[i+1][0]%mod;
		dp[x][1]=(dp[x][1]+1ll*tmp*dp[son[i]][1]%mod)%mod;
		dp[x][2]=(dp[x][2]+1ll*tmp*dp[son[i]][1]%mod)%mod;
		// 1.2
		tmp=1ll*pre[i-1][0]*suf[i+1][0]%mod;
		dp[x][1]=(dp[x][1]+1ll*tmp*dp[son[i]][1]%mod)%mod;
		//2.1
		tmp=1ll*pre[i-1][0]*suf[i+1][0]%mod;
		dp[x][2]=(dp[x][2]+2ll*tmp*dp[son[i]][2]%mod)%mod;
	}
}
int main()
{
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	n=rd(),m=rd(),pow2[0]=1;
	for(int i=1;i<=m;i++) pow2[i]=pow2[i-1]*2ll%mod;
	for(int i=1,x,y;i<=m;i++) x=rd(),y=rd(),add(x,y),add(y,x);
	for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,0);
	for(int i=1;i<=n;i++) if(!vis[i]) sum++,Find(i);
	for(int i=1;i<=n;i++) for(int j=hea[i];j;j=nex[j]) if(i<ver[j])
	{
		if(isge[j]) g[bel[i]].pb(bel[ver[j]]),g[bel[ver[j]]].pb(bel[i]);
		else muti=muti*2ll%mod;
	}
	solve(1,0);
	printf("%lld\n",1ll*dp[1][2]*muti%mod);
	fclose(stdin);
	fclose(stdout);
	return 0;
}
