#include<bits/stdc++.h>
#define rep(i,l,r) for(int i=l;i<=r;++i)
#define per(i,r,l) for(int i=r;i>=1;--i)
#define N 400005
#define int long long
using namespace std;

int read(){
	int x=0,w=1;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return x*w;
}

const int mod = 1e9+7;
int n,ans,m,tt;
int head[N],f[N];
struct node{int to,nxt;}edge[N<<1];
bool vis[N],vis1[N],vis2[N];
struct Edge{int u,v;}e[N];

int find(int x){
	if(x==f[x]) return x;
	return f[x]=find(f[x]);
}

bool check(){
	rep(i,1,n) {f[i]=i;}
	rep(i,1,m){
		if(!vis2[i]) continue;
		int f1=find(e[i].u),f2=find(e[i].v);
		if(f1==f2)continue;
		f[f1]=f2;
	}
//	if(cnt==2) cout<<f[1]<<" "<<f2<<endl;
	rep(i,1,n) rep(j,1,n){
		if(vis[i]&&vis[j]&&i!=j) {
			int f1=find(i),f2=find(j);
			if(f1!=f2) return false;
		}
	}
	return true;
}
void dfs1(int x){
	if(x>m) {
		rep(i,1,m) vis2[i]=1;
		int flag=1;
		rep(i,1,m) {
			if(!vis1[i]) {
				vis2[i]=0;
				if(!check()) {
					flag=0;
					break;
				}
				vis2[i]=1;
			} 
		}
		if(flag) ans++;
		return;
	}
	vis1[x]=1; dfs1(x+1);
	vis1[x]=0; dfs1(x+1);
}
void work(){
	int flag=0;
	rep(i,1,n) if(vis[i]==1) flag=1;
	rep(i,1,m) vis1[i]=0;
	if(!flag) return ;
	dfs1(1);
}
void dfs(int x){
	if(x>n) {
		work(); tt++;
		return ;
	}
	vis[x]=1; dfs(x+1);
	vis[x]=0; dfs(x+1);
}

void solve1(){
	rep(i,1,m){
		int u=read(),v=read();
		e[i].u=u;e[i].v=v;
	}
	dfs(1);
	printf("%lld\n",ans);
}
int qpow(int x,int k){
	int res=1;
	for(;k;x=x*x%mod,k>>=1) if(k&1) res=res*x%mod;
	return res;
}
void solve2(){
	rep(i,1,m) {
		int u=read(),v=read();
	}
	int ans=0;
	rep(i,1,n) {
		if(i<=2) ans=(ans+(n-i+1)*qpow(2,n-i)%mod)%mod;
		else ans=(ans+qpow(2,i-2)*(n-i+1)*qpow(2,n-i)%mod)%mod;	
	}
	printf("%lld\n",ans);
}

signed main(){
	
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	
	n=read(); m=read();
	if(n<=16) solve1();
	else solve2();
	return 0;
}
/*
4 4
1 2
2 3
3 1
1 4
*/

