#include<bits/stdc++.h>
using namespace std;
#define int long long 
inline int read() {
	int x = 0, f = 1; char c = getchar();
	while (c < '0' || c > '9') {if (c == '-') f = -f; c = getchar();}
	while (c >= '0' && c <= '9') {x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();}
	return x * f;
}
const int N = 2e6 + 10;
int n, m;
int tot, head[N], Next[N], ver[N];
inline void add_edge(int u, int v) {
	ver[++tot] = v; Next[tot] = head[u]; head[u] = tot;
}
struct Edge{
	int u, v;
}E[N<<2];
int v[N], e[N], fa[20], ans;
inline int find(int x) {return x == fa[x] ? x : fa[x] = find(fa[x]);}
inline void getans() {
	int cnt = m;
	for (int i = 1; i <= m; ++ i) {
		for (int j = 1; j <= n; ++ j) fa[j] = j;
		for (int j = 1; j <= m; ++ j) {
			if (j == i) continue;
			int fx = find(E[j].u), fy = find(E[j].v);
			if (fx != fy) fa[fy] = fx;
		}
		int flag = -1;
		for (int j = 1; j <= n; ++ j) 
			if (v[j]) { flag = find(j); break;}
		if (flag == -1) break;
		int cannot = 0;
		for (int j = 1; j <= n; ++ j) 
			if (v[j] && find(j) != flag)  {cannot = 1; break;}
		cnt -= cannot;
	}
	int t = 0;
	for (int i = 1; i <= n; ++ i)
		if (v[i]) ++ t;
	if (!t) return;
	ans += (1 << cnt);
}
inline void dfs1(int x) {
	if (x > n) {
		getans();
		return;
	}
	v[x] = 1;
	dfs1(x + 1); 
	v[x] = 0;
	dfs1(x + 1);
}
signed main () {
	freopen("barrack.in", "r", stdin);
	freopen("barrack.out", "w", stdout);
	n = read(); m = read();
	for (int i = 1; i <= m; ++ i) {
		int u = read(), v = read();
		E[i] = (Edge) {u, v};
	}
	if (n <= 16 && m <= 25) {
		dfs1(1);
		printf("%lld\n", ans);
	} else {
		
	}
	return 0;
}
