#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<deque>
#include<cmath>
#include<set>
#include<map>
#include<string>
#include<cstring>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const int N=5e5+10;
const int M=1e6+10;
struct Node{
	int from,to,nxt;
	bool flag;
}edge[M<<1];
int head[N],tot;
void init()
{
	memset(head,-1,sizeof(head));
	tot=0;
}
void add(int u,int v)
{
	edge[tot].from=u;
	edge[tot].flag=true;
	edge[tot].to=v;
	edge[tot].nxt=head[u];
	head[u]=tot++;
}
ll et[M];
int num[N];
int n,m;
int bcc;
bool vis[N];
void DFS(int u)
{
	for(int i=head[u];~i;i=edge[i].nxt)
	{
		if(edge[i].flag==false) continue;
		int v=edge[i].to;
		if(vis[v]) continue;
		vis[v]=1;
		DFS(v);
	}
}
bool judge(int u)
{
	memset(vis,0,sizeof(vis));
	vis[u]=1;
	DFS(u);
	bool tp=1;
	for(int i=1;i<=n;i++)
	{
		if(num[i] && (!vis[i])) tp=0;
	}
	return tp;
}
int main()
{
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	init();
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	if(n>=100)
	{
		printf("0\n");
		return 0;
	}
	et[0]=1;
	for(int i=1;i<M;i++)
	{
		et[i]=et[i-1]*2%mod;
	}
	int s=0;
	ll ans=0;
	for(int i=1;i<(1<<n);i++)
	{
		memset(num,0,sizeof(num));
		for(int j=1;j<=n;j++)
		{
			if((1<<(j-1))&i) num[j]=1,s=j;
		}
		bcc=0;
		if(judge(s))
		{
			for(int k=0;k<tot;k+=2)
			{
				edge[k].flag=false;
				edge[k^1].flag=false;
				if(judge(s)==0) bcc++;
				edge[k].flag=true;
				edge[k^1].flag=true;
			}
		}
		ans+=et[m-bcc];
		ans%=mod;
	}
	printf("%lld\n",ans%mod);
	return 0;
}