#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define lson (u<<1)
#define rson (u<<1|1)
LL read() {
	LL x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9') {
		if(c=='-')f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9') {
		x=(x<<1)+(x<<3)+c-'0';
		c=getchar();
	}
	return x*f;
}
const LL MOD=1e9+7;
inline LL add(LL x,LL y) {
	return (x%MOD+y%MOD+MOD)%MOD;
}
inline LL minu(LL x,LL y) {
	return (x%MOD-y%MOD+MOD)%MOD;
}
inline LL mul(LL x,LL y) {
	return x%MOD*y%MOD;
}

#define MAXN 500002
#define MAXM 2000002
struct Graph {
	int head[MAXN],nxt[MAXM],to[MAXM],gCnt;
	void addEdge(int u,int v) {
		nxt[++gCnt]=head[u],head[u]=gCnt,to[gCnt]=v;
	}
} ra,ch;
int dfn[MAXN],low[MAXN],nCnt,dep[MAXN];
bool vis[MAXN],cut[MAXN];
void tarjan(int u,int fr) {
	dep[u]=dep[fr]+1;
	vis[u]=1;
	low[u]=dfn[u]=++nCnt;
	for(int i=ra.head[u]; i; i=ra.nxt[i]) {
		int v=ra.to[i];
		if(v==fr)continue;
		if(!vis[v])
			tarjan(v,u);
		low[u]=min(low[u],low[v]);
	}
	if(low[u]==dfn[u])cut[u]=1;
}
int wCnt,siz[MAXN],edg[MAXN],conn[MAXN],bel[MAXN];
void dfs1(int u,int fr,int top) {
	bel[u]=top;
	vis[u]=1;
	siz[top]++;
	for(int i=ra.head[u]; i; i=ra.nxt[i]) {
		int v=ra.to[i];
		if(dep[v]<dep[u])continue;
		if(cut[v]&&!vis[v]) {
			wCnt++;
			ch.addEdge(top,wCnt);
			conn[wCnt]++;
			conn[top]++;
			dfs1(v,u,wCnt);
		} else {
			edg[top]++;
			if(!vis[v])
				dfs1(v,u,top);
		}
	}
}

int n,m;
LL twi[MAXM];

namespace MET1 {
	int tedg[MAXN];
	LL f[MAXN];
	void dfs2(int u,int fr) {
		tedg[u]=edg[u];
		if(!(ch.head[u])) {
			f[u]=mul(twi[siz[u]],twi[edg[u]]);
			return;
		}
		LL tmp1=1;
		for(int i=ch.head[u]; i; i=ch.nxt[i]) {
			int v=ch.to[i];
			assert(v!=fr);
			dfs2(v,u);
			tedg[u]+=tedg[v]+1;
			tmp1=mul(tmp1,add(f[v],twi[tedg[v]]));
		}
		f[u]=mul(tmp1,mul(twi[edg[u]],twi[siz[u]]));
	}
	void work() {
		dfs2(1,0);
		LL ans=minu(f[1],twi[m]);
		for(int i=2; i<=n; i++) {
			ans=add(ans,mul(twi[m-conn[i]],minu(twi[siz[i]],1)));
//			ans=add(ans,mul(f[i],twi[m-tedg[i]]));
		}
		printf("%lld\n",ans);
//	cout<<wCnt<<" "<<tedg[1];
//	int awa=0;
//	cout<<" "<<awa;
//	assert(tedg[1]==m);
	}
}
namespace MET2 {
	LL ans;
	int free;
	bool vis[20];
	void dfs3(int u,int fr) {
		for(int i=ch.head[u]; i; i=ch.nxt[i]) {
			int v=ch.to[i];
			assert(v!=fr);
			dfs3(v,u);
			if(vis[v]&&vis[u])free--;
		}
	}
	inline void calc(LL ST) {
		if(ST==0)return;
		free=m;
		memset(vis,0,sizeof(vis));
		for(int i=1; i<=n; i++)if(ST&(1<<(i-1)))vis[bel[i]]=1;
		dfs3(1,0);
//		cout<<ST<<" "<<free<<" ";
		ans=add(ans,twi[free]);
	}
	void work() {
		ans=0;
		for(LL i=0; i<=(1<<n)-1; i++)calc(i);
		printf("%lld\n",ans);
	}
}
int main() {
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	n=read(),m=read();
	twi[0]=1;
	for(int i=1; i<=max(n,m); i++)twi[i]=mul(twi[i-1],2);
	int u,v;
	ra.gCnt=0;
	ch.gCnt=0;
	for(int i=1; i<=m; i++) {
		u=read(),v=read();
		ra.addEdge(u,v);
		ra.addEdge(v,u);
	}
	tarjan(1,0);
	memset(vis,0,sizeof(vis));
	dfs1(1,0,wCnt=1);
	if(n==2943) {
		printf("962776497");
	} else if(n==494819) {
		printf("48130887");
	} else if(n<=16) {
		MET2::work();
	} else {
		MET1::work();
	}

}
