#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD=1e9+7;
const int N=1e4+9;
int n,m;
int ans1;
ll ans=0;
int ver[N*2],head[N],Next[N*2],tot,from[N*2],fa[N];
int du[N];
void add(int x,int y){
	ver[++tot]=y,Next[tot]=head[x],head[x]=tot,from[tot]=x;
}
int get(int x){
	if (fa[x]==x) return x;
	return get(fa[x]);	
}
void merge(int x,int y){
	fa[get(x)]=get(y);
}
struct node{
	int l,r;
}a1[N];
ll C[5009][5009];
int a[N],f[N][N];
bool flag;
void dfs2(int x,int yx,int we){
	//if (yx>ans1) return;
	if (x>m){
		int fa=get(a[1]);
		flag=1;
		for (int i=2;i<=we;i++)
			if (get(a[i])!=fa) {
				flag=0;
				break;
			}
		if (flag==0) return;else{
			ans1++;
			return;
		}	
	}
	int fa1=get(from[x]);
	//a1[yx+1].l=from[x],a1[yx+1].r=ver[x];
	merge(from[x],ver[x]);
	
	
	dfs2(x+1,yx+1,we);
	fa[fa1]=fa1;
	dfs2(x+1,yx,we);
	
	
}
ll solve(int we){
	ans1=0;
	for (int i=1;i<=n;i++){
		fa[i]=i;
	}
	flag=1;
	dfs2(1,0,we);
	
	return ans1;
}
void dfs(int yx,int x){
	
	
	if (yx!=0&&x>n){
		ll e=solve(yx);
		ans=(ans+e)%MOD;
		return;
	}
	if (x>n) return;	 	
	a[yx+1]=x;
	dfs(yx+1,x+1);
	dfs(yx,x+1);
}
void build(){
	for (int i=0;i<=5000;i++)
		C[i][0]=C[i][i]=1;
	for (int i=2;i<=5000;i++){
		for (int j=1;j<=i-1;j++)
				C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
		//if (i==8) break;
	}
	
}
int main(){
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	build();
	bool fla=0;
	scanf("%d%d",&n,&m);
	memset(f,0x3f,sizeof(f));
	for (int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y);
		du[x]++,du[y]++;
		if (du[x]>2||du[y]>2){
			fla=1;
		}
	}
	//if (fla==1) solve2();
	dfs(0,1);
	printf("%lld\n",ans);
	return 0;
}

 
 