#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int d=0;
	char c=getchar();
	while(c<'0'||c>'9')c=getchar();
	while(c>='0'&&c<='9'){d=(d<<3)+(d<<1)+c-'0';c=getchar();}
	return d;
}
const int N=5e5+5,M=1e6+5;
int n,m,ans,tot;
int front;
int ver[M*2],nxt[M*2],head[N],cnt;
bool pl1[N],pl2[M];
bool pl[N];
void add(int x,int y){
	ver[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;
}
bool bfs(){
	for(int i=1;i<=n;i++)
		pl[i]=false;
	int cnt=1;
	if(cnt==tot)
		return true;
	queue<int> q;
	q.push(front);
	pl[front]=true;
	while(!q.empty()){
		int x=q.front();
		q.pop();
		for(int i=head[x];i;i=nxt[i]){
			int y=ver[i];
			if(pl[y]||(!pl2[i/2]))
				continue;
			q.push(y);
			pl[y]=true;
			if(pl1[y]){
				cnt++;
				if(cnt==tot)
					return true;
			}
		}
	}
	return false;
}
void dfs2(int x){
	if(x>m){
		if(bfs())
			ans++;
		return ;
	}
	dfs2(x+1);
	pl2[x]=true;
	dfs2(x+1);
	pl2[x]=false;
}
void dfs1(int x){
	if(x>n){
		if(front)
			dfs2(1);
		return ;
	}
	dfs1(x+1);
	pl1[x]=true;
	tot++;
	int d=front;
	front=x;
	dfs1(x+1);
	tot--;
	front=d;
	pl1[x]=false;
}
int main(){
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	ios::sync_with_stdio(false);
	cout.tie(0);
	n=read(),m=read();
	cnt=1;
	for(int i=1;i<=m;i++){
		int u=read(),v=read();
		add(u,v);
		add(v,u);
	}
	dfs1(1);
	cout<<ans<<endl;
	return 0;
}
