// Fresh Peach Heart Shower
#include <bits/stdc++.h>
#define pb push_back
#define MP std::make_pair
#define ALL(x) (x).begin(),(x).end()
#define mem(x,y) memset(x,y,sizeof(x))
#ifdef _LOCAL_
#define dprintf(x...) fprintf(stderr,x)
#else
#define dprintf(x...) 42
#endif
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,b,a) for(int i=(b);i>=(a);--i)
typedef std::vector<int > poly;
typedef std::pair<int,int > pii;
void setIn(std::string s){freopen(s.c_str(),"r",stdin);}
void setOut(std::string s){freopen(s.c_str(),"w",stdout);}
void setIO(std::string s){setIn(s+".in"),setOut(s+".out");}
template <class t> inline bool ckmin(t&x,t y){if(x>y)return x=y,1;return 0;}
template <class t> inline bool ckmax(t&x,t y){if(x<y)return x=y,1;return 0;}
inline int lowbit(int x){return x&(-x);}
const int MaxN=1e6+50;
const int p=1e9+7;
struct mint
{
	int v;
	mint(){v=0;}
	bool check(long long x){return 0<=x&&x<p;}
	mint(int x)
	{
		if(check(x))v=x;
		else v=(x%p+p)%p;
	}
	mint(long long x)
	{
		if(check(x))v=x;
		else v=(x%p+p)%p;
	}
	mint operator + (const mint &nt) const
	{
		return mint(v>=p-nt.v?v-p+nt.v:v+nt.v);
	}
	mint operator - (const mint &nt) const
	{
		return mint(v>=nt.v?v-nt.v:v-nt.v+p);
	}
	mint operator * (const mint &nt) const
	{
		return mint(1LL*v*nt.v%p);
	}
	int fpow(int a,long long b) const
	{
		int ret=1;
		for(;b;b>>=1,a=1LL*a*a%p)if(b&1)ret=1LL*ret*a%p;
		return ret;
	}
	mint pow(long long b) const{return mint(fpow(v,b));}
	mint inv() const{return mint(fpow(v,p-2));}
	mint operator / (const mint &nt) const{return nt.inv()*v;}
	mint operator += (const mint &nt){return *this=*this+nt;}
	mint operator -= (const mint &nt){return *this=*this-nt;}
	mint operator *= (const mint &nt){return *this=*this*nt;}
	mint operator /= (const mint &nt){return *this=*this/nt;}
};
struct Edge
{
	int nxt,to;
}E[MaxN<<1];
int hd[MaxN],en=-1;
int used[MaxN<<1];
void adde(int u,int v)
{
	E[++en]=(Edge){hd[u],v},hd[u]=en;
	std::swap(u,v);
	E[++en]=(Edge){hd[u],v},hd[u]=en;
}
int n,m;
poly G[MaxN];
int dfn[MaxN],low[MaxN],vis[MaxN],st[MaxN],tp,dfncnt;
int col[MaxN],cnt[MaxN],scc;
void tarjan(int u)
{
	dfn[u]=low[u]=++dfncnt;
	vis[u]=1,st[tp++]=u;
	for(int i=hd[u];~i;i=E[i].nxt)
	{
		if(used[i])continue;
		used[i]=used[i^1]=1;
		int v=E[i].to;
		if(!dfn[v])tarjan(v),ckmin(low[u],low[v]);
		else if(vis[v])ckmin(low[u],dfn[v]);
	}
	if(dfn[u]==low[u])
	{
		++scc;
		do vis[st[--tp]]=0,col[st[tp]]=scc,++cnt[scc];
		while(st[tp]!=u);
	}
}
mint inv2,ans;
mint dp[MaxN][2],g[2];
std::map<pii ,int > ecnt;
void dfs(int u,int fa)
{
	vis[u]=1;
	dp[u][0]=1;
	dp[u][1]=mint(2).pow(cnt[u])-1;
	mint cur=dp[u][1];
	for(auto v:G[u])if(v!=fa)
	{
		if(vis[v])continue;
		dfs(v,u);
		g[0]=g[1]=0;
		rep(i,0,1)rep(j,0,1)
			g[i|j]+=dp[u][i]*dp[v][j]*(j?inv2:1);
		dp[u][0]=g[0],dp[u][1]=g[1];
		cur*=(dp[v][0]+dp[v][1]*inv2);
	}
	ans+=cur;
}
signed main(void)
{
#ifndef _LOCAL_
	std::ios::sync_with_stdio(false),std::cin.tie(0);
#endif

	setIO("barrack");

	inv2=mint(2).inv();
	std::mem(hd,-1);
	std::cin>>n>>m;
	int u,v;
	rep(i,1,m)std::cin>>u>>v,adde(u,v);
	tarjan(1);
//	dprintf("scc %d\n",scc);
	rep(u,1,n)for(int i=hd[u];~i;i=E[i].nxt)
	{
		int v=E[i].to;
		if(col[u]!=col[v])G[col[u]].pb(col[v]);
//		++ecnt[MP(col[u],col[v])];
	}
	for(auto i:ecnt)assert(i.second<=1);
	std::mem(vis,0);
	dfs(1,0);
	std::cout<<(ans*mint(2).pow(m)).v<<'\n';
	return 0;
}


