#include<bits/stdc++.h>
using namespace std;
const int N=5e5+7;
const int HgS=1e9+7;
int read(){
	char c;
	int x=0;
	while(!isdigit(c=getchar()));
	while(isdigit(c)){
		x=(x<<3)+(x<<1)+(c^48);
		c=getchar();
	}
	return x;
}
int qpow(int a,int b){
	int res=1;
	while(b){
		if(b&1)
			res=1ll*res*a%HgS;
		a=1ll*a*a%HgS;
		b>>=1;
	}
	return res;
}
struct edge{
	int u,v;
	edge(int u=0,int v=0):u(u),v(v){}
}e[N];
int n,m,u,v,res,f[N];
vector<int>ch;
int get(int x){
	return x==f[x]?x:f[x]=get(f[x]);
}
void merge(int x,int y){
	x=get(x);
	y=get(y);
	if(x==y)
		return;
	f[y]=x;
}
namespace _0107{
	bool chk(){
		return n<=16&&m<=25;
	}
	void dfs(int x,int fir){
		if(x>n){
			if(!fir)
				return;
			int cnt=m;
			for(int i=1;i<=m;++i){
				for(int j=1;j<=n;++j)
					f[j]=j;
				for(int j=1;j<=m;++j){
					if(i==j)
						continue;
					merge(e[j].u,e[j].v);
				}
				for(auto u:ch){
					if(get(u)^get(fir)){
						--cnt;
						break;
					}
				}
			}
			res=(res+qpow(2,cnt))%HgS;
			return;
		}
		dfs(x+1,fir);
		if(!fir)
			fir=x;
		ch.push_back(x);
		dfs(x+1,fir);
		ch.pop_back();
	}
	void solve(){
		dfs(1,0);
		printf("%d\n",res);
	}
}
namespace _1011{
	bool chk(){
		if(m>n-1)
			return 0;
		for(int i=1;i<=m;++i){
			if(e[i].u!=i||e[i].v!=i+1)
				return 0;
		}
		return 1;
	}
	void solve(){
		if(n==1)
			puts("1");
		else
			printf("%lld\n",(1ll*n*qpow(2,n-1)+((n*(n-1ll)/2)%HgS)*qpow(2,n-2))%HgS);
	}
}
int main(){
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	n=read();
	m=read();
	for(int i=1;i<=m;++i){
		u=read();
		v=read();
		e[i]=edge(u,v);
	}
	if(_0107::chk())
		_0107::solve();
	else if(_1011::chk())
		_1011::solve();
	return 0;
}