#include<bits/stdc++.h>
using namespace std;
#define maxn int(1e5+7)
#define ll long long
#define mod int(1e9+7)
#define maxm int(2e6+7)
ll C[1005][1005];
int cnt,num_edge,n,s,ans;
int head[maxn],fa[maxn],id[maxn],vis[maxn],t[maxn];
struct Edge{
	int next,to;
}edge[maxm];
inline void add(int from,int to){
	num_edge++;
	edge[num_edge].next=head[from];
	edge[num_edge].to=to;
	head[from]=num_edge;
}
inline int read(){
	int num=0,x=1;
	char c;
	c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-'){
			x=-1;
		}
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		num=num*10+c-48;
		c=getchar();
	}
	return num*x;
}
void init(){
	C[0][0]=1;
	C[1][0]=C[1][1]=1;
	for(int i=2;i<=n;i++){
		C[i][0]=1;
		for(int j=1;j<=i;j++){
			C[i][j]=C[i-1][j]+C[i-1][j-1];
			C[i][j]%=mod;
		}
	}
}
int find(int x){
	if(x!=fa[x]){
		return fa[x]=find(fa[x]);
	}
	return x;
}
void dfs(int x){
	id[x]=++cnt;
	for(int i=head[x];i;i=edge[i].next){
		int v=edge[i].to;
		if(vis[v]){
			int y=find(id[v]),z=find(id[x]);
			fa[y]=z;
		}
		else{
			vis[v]=1;
			dfs(v);
			if(fa[id[v]]!=id[v]){
				fa[find(id[x])]=fa[id[v]];
			}
		}
	}
}
ll jie(int x){
	ll ret=1;
	for(int i=1;i<=x;i++){
		ret+=C[x][i];
		ret%=mod;
	}
	return ret;
}
void dp(){
	for(int i=1;i<=n;i++){
		if(t[fa[find(id[i])]]==0){
			s++;
		}
		t[fa[find(id[i])]]++;
	}
	//cout<<s;
	ans=s*jie(s-1);
	for(int i=0;i<=s-1;i++){//edge
		for(int j=2;j<=s-i;j++){//point
			ans+=C[j-2][s-i-2]*jie(i);
			ans%=mod;
		}
	}
}
int main(){
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	int m,u,v;
	n=read();
	m=read();
	init();
	for(int i=1;i<=m;i++){
		u=read();
		v=read();
		add(u,v);add(v,u);
	}
	for(int i=1;i<=n;i++){
		fa[i]=i;
	}
	vis[1]=1;
	dfs(1);
	dp();
	for(int i=1;i<=n;i++){
		//cout<<id[i]<<" ";
		//cout<<t[i]<<" ";
		if(t[i]>=1){
			ans*=t[i];
			//cout<<t[i]<<" ";
		}
	}
	cout<<ans%mod;
	return 0;
}
/*4 4
1 2
2 3
3 4
3 1
*/
