#include<bits/stdc++.h>
using namespace std;
namespace __Plozia__
{
typedef long long ll;
template<typename type>
inline void chmin(type &x,const type &y)
{
	if(y<x)
		x=y;
}
constexpr int Max=1e6+100;
constexpr ll mod=1000000007;
ll pow2[Max*2],f[Max];
vector<int>e[Max],e2[Max];
int dfn[Max],low[Max],bel[Max],siz[Max],id[Max],ec[Max],sum[Max],order=0;
int find(int i)
{
	return i==bel[i]?i:bel[i]=find(bel[i]);
}
void unite(int x,int y)
{
	x=find(x),y=find(y);
	if(x!=y)
		bel[x]=y,siz[y]+=siz[x];
}
int n,m;
void tarjan(int u,int from)
{
	dfn[u]=low[u]=++order;
	for(auto v:e[u])
		if(v!=from)
		{
			if(!dfn[v])
			{
				tarjan(v,u),chmin(low[u],low[v]);
				if(low[v]<=dfn[u])
					unite(u,v);
			}
			else
				unite(u,v),chmin(low[u],dfn[v]);
		}
}
void dfs(int u,int from)
{
	sum[u]=ec[u];
	f[u]=1;
	ll s=1;
	for(auto v:e2[u])
		if(v!=from)
		{
			dfs(v,u);
			sum[u]+=sum[v]+1;
			(f[u]*=(f[v]+pow2[sum[v]+1])%mod)%=mod;
			(s*=pow2[sum[v]+1])%=mod;
		}
	(f[u]*=pow2[siz[u]]*pow2[ec[u]]%mod)%=mod;
	f[u]=(f[u]-s*pow2[ec[u]]%mod+mod)%mod;
}
signed plozia_main()
{
	cin>>n>>m;
	pow2[0]=1;
	for(int i=1;i<=m;++i)
		pow2[i]=pow2[i-1]*2%mod;
	for(int i=1,u,v;i<=m;++i)
		cin>>u>>v,e[u].push_back(v),e[v].push_back(u);
	for(int i=1;i<=n;++i)
		bel[i]=i,siz[i]=1;
	tarjan(1,0);
	for(int u=1;u<=n;++u)
		for(auto v:e[u])
			if(u<v)
			{
				int x=find(u),y=find(v);
				if(x==y)
					++ec[x];
				else
					e2[x].push_back(y),e2[y].push_back(x);
			}
	int rt=find(1);
	dfs(rt,0);
	ll ans=0;
	for(int i=1;i<=n;++i)
		if(i==find(i))
		{
			if(i!=rt)
				(ans+=f[i]*pow2[m-sum[i]-1]%mod)%=mod;
			else
				(ans+=f[i])%=mod;
		}
	cout<<ans<<"\n";
	return 0;
}
}
signed main()
{
	freopen("barrack.in","r",stdin),freopen("barrack.out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(nullptr),cout.tie(nullptr);
	__Plozia__::plozia_main();
	return 0;
}