#include<bits/stdc++.h>
//#define int long long //__int128
const int MAXN = 1e5+3;
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;//0x3f3f3f3f3f3f3f3f;
using namespace std;
int n,m;
struct G {
	vector<int> gr[MAXN];
	vector<int> operator[](int idx) {
		return gr[idx];
	}
	inline void add(int u,int v) {
		gr[u].push_back(v);
		gr[v].push_back(u);
	}
	inline void clear(int n) {
		for(int i =1; i<=n; i++)gr[i].clear();
	}
} g;
int fa[MAXN];
inline void build(int n) {
	for(int i = 1; i<=n; i++)fa[i] = i;
}
inline int find(int x) {
	return x==fa[x]?x:fa[x] = find(fa[x]);
}
inline void merge(int u,int v) {
	fa[find(u)] = find(v);
}
bool vis[MAXN];
inline void dfs(int u) {
	vis[u] = true;
	for(auto v:g[u]) {
		if(vis[v])continue;
		merge(u,v);
		dfs(v);
	}
}
inline int check(int st) {
	int rt = 0;
	build(n);
	memset(vis,0,sizeof(int)*(n+5));
	for(int i = 1; i<=n; i++)if(!vis[i])dfs(i);
	for(int i = 0; i<n; i++)
		if(st>>i&1) {
			rt = find(i+1);
			break;
		}
	for(int i = 0; i<n; i++) {
		if(st>>i&1)
			if(find(i+1)!=rt)return 0;
	}
	return 1;
}
struct E {
	int u,v;
} e[MAXN];
int ans = 0;
void work() {
	cin>>n>>m;
	for(int i = 1; i<=m; i++)cin>>e[i].u>>e[i].v;
	for(int i =1; i<(1<<n); i++) {
		for(int j = 0; j<(1<<m); j++) {
			g.clear(n);
			for(int k = 0; k<m; k++) {
				if(j>>k&1)g.add(e[k+1].u,e[k+1].v);
			}
			ans+=check(i);
		}
	}
	cout<<ans<<"\n";
	return;
}
signed main() {
//	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	work();
	return 0;
}
