#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = 500010, M = N * 2, mod = 1e9 + 7;

int n, m, root;
int e[M], ne[M], h[N], idx;
int cnt[N], nlx[N], lx[N];
bool st[N];

inline void add(int a, int b){
	e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

bool check(int state, int i){
	if (state & (1 << (i >> 1))) return true;
	else return false ;
}

bool dfs(int statee, int statep){
	int tot = 0;
	queue<int> q;
	bool stt[15],att[15];
	memset(stt, false , sizeof stt);
	memset(att, false , sizeof att);
	for (int i = 0;i < n; ++ i)
		if (statep & (1 << i)){
			if (!q.size()) {
				q.push(i + 1);
				stt[i + 1] = true;
			}
			att[i + 1] = true;
			tot ++;
		}
	
	int now = 1;
	while (q.size()){
		int t = q.front();
		q.pop();
		for (int i = h[t]; i != -1; i = ne[i]){
			int j = e[i];
			if (!check(statee, i) || stt[j]) continue;
			if (att[j]) now ++;
			q.push(j);
			stt[j] = true;
		}
	}
	if (now == tot) return true;
	else return false;
}

int main(){
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	scanf("%d%d", &n, &m);
	memset(h, -1, sizeof h);
	for (int i = 1;i <= m; ++i){
		int u, v;
		scanf("%d%d", &u, &v);
		add(u, v), add(v, u);
		cnt[u] ++, cnt[v] ++;
	}
	
	int ans = 0;
	for (int edge = 0;edge < pow(2, m); ++ edge)
		for (int point = 1;point < pow(2, n); ++ point)
			if (dfs(edge, point))
				ans ++;
	cout << ans << endl;
	
//	else {
//		int root;
//		LL ans = 0;
//		for (int i = 1;i <= n; ++i)
//			if (cnt[i] >= 2) {
//				root = i;
//				break;
//			}
//		 
//		queue<int> q;
//		for (int i = 1;i <= n; ++ i)
//			if (cnt[i] == 1){
//				ans ++;                                    
//				q.push(i);
//				st[i] = true;				 
//				lx[i] = nlx[i] = 1;
//			}
//		while (q.size()){
//			int t = q.front();
//			q.pop();
//			for (int i = h[t];i != -1;i = ne[i]){
//				int j = e[i];
//				if (st[j]) continue;
//				lx[j] += lx[t] + nlx[t];
//				nlx[j] += nlx[t];
//				cnt[j] --;
//				if (cnt[j] == 1) q.push(j); 
//			}
//		}
//	}
	return 0;
}