#include<bits/stdc++.h>
using namespace std;
inline read(){
	register int o=0,f=0;
	register char a=getchar();
	while(a<'0'||'9'<a){
		if(a=='-')  f=1;
		a=getchar();
	}
	while('0'<=a&&a<='9')  o=(o<<3)+(o<<1)+(a^'0'),a=getchar();
	return f==1?-o:o;
}
struct node{
	int to,id;
}_;
int n,m,u,v,s[500003],p1[500003],p2[1000003],f[500003],t,i;
long long p[2000003]={1},c[500003][3],mod=1000000007,ans;
vector<node>w[500003];
void Dfs(int x,int lost){
	s[x]=1,c[x][0]=c[x][1]=c[x][2]=1;
	for(int e=w[x].size(),i=0;i<e;i++){
		int way=w[x][i].to;
		if(way==lost)  continue;
		Dfs(way,x),s[x]+=s[way]; 
		long long sum=0;
		sum=(sum+(c[way][0]+c[way][1])%mod*2%mod)%mod;
		sum=(sum+c[way][2])%mod,c[x][1]=c[x][1]*sum%mod;
		c[x][2]=c[x][2]*c[way][2]%mod,c[x][0]=c[x][0]*sum%mod;
	}
	c[x][0]=(c[x][0]-c[x][2]+mod)%mod;
}
void dfs(int x,int lost){
	for(int e=w[x].size(),i=0;i<e;i++){
		int way=w[x][i].to;
		if(f[way]==t)  continue;
		dfs(way,x);
	}
}
void check2(int x){
	if(x>m){
		t++;
		for(i=1;i<=n;i++)
			if(p1[i]==1)  dfs(i,0);
		for(i=1;i<=n;i++)
			if(f[i]!=t)  return;
		return ans++,void();
	}
	p2[x]=0,check2(x+1),p2[x]=1,check2(x+1);
}
void check1(int x){
	if(x>n)  return check2(1),void();
	p1[x]=0,check1(x+1),p1[x]=1,check1(x+1);
}
int main(){
	freopen("barrack.in","r",stdin),freopen("barrack.out","w",stdout);
	for(n=read(),m=read(),i=1;i<=2000000;i++)  p[i]=p[i-1]*2%mod;
	for(i=1;i<=m;i++)  u=read(),v=read(),_.to=u,_.id=i*2-1,w[v].push_back(_),_.to=v,_.id=i*2,w[u].push_back(_);
	if(m==n-1)  return Dfs(1,0),printf("%lld",(c[1][0]+c[1][1])%mod),0;
	return check1(1),printf("%lld",ans),0;
}
//sto yk orz
