#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
#define MP make_pair
#define PB push_back
#define inf 1000000007
#define rep(i,n) for(int i = 0; i < (int)(n); ++i)
#define all(x) (x).begin(),(x).end()

template<typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val){
    std::fill( (T*)array, (T*)(array+N), val );
}
 
template<class T> inline bool chmax(T &a, T b){
    if(a<b){
        a = b;
        return true;
    }
    return false;
}

template<class T> inline bool chmin(T &a, T b){
    if(a>b){
        a = b;
        return true;
    }
    return false;
}
class UnionFind {
private:
    int sz;
    vector<int> par, size_;
public:
    UnionFind(){}
    UnionFind(int node_size) : sz(node_size), par(sz), size_(sz, 1){
        iota(par.begin(), par.end(), 0);
    }
    int find(int x){
        if(par[x] == x) return x;
        else return par[x] = find(par[x]);
    }
    void unite(int x,int y){
        x = find(x), y = find(y);
        if(x == y) return;
        if(size_[x] < size_[y]) swap(x,y);
        par[y] = x;
        size_[x] += size_[y];
    }
    int size(int x){
        x = find(x);
        return size_[x];
    }
    bool same(int x,int y){
        return find(x) == find(y);
    }
};
int main(){
    int n,m;
    cin >> n >> m;
    vector<pair<int,int> > p;
    rep(i,m){
        int a,b;
        cin >> a >> b;
        a--;b--;
        p.push_back(MP(a,b));
    }
    ll ans = 0;
    rep(bit,1<<n){
        UnionFind uf(2*n);
        ll res = 1;
        rep(j,m){
            int a = p[j].first;
            int b = p[j].second;
            if(((bit>>a)&1)&&((bit>>b)&1)){
                res = 0;
            }else{
                if(((bit>>a)&1)||((bit>>b)&1)){

                }else{
                    uf.unite(a,b+n);
                    uf.unite(b,a+n);
                }
            }
        }
        vector<bool> p(2*n);

        rep(j,n){
            if((bit>>j)&1)continue;
            if(p[uf.find(j)]||p[uf.find(j+n)])continue;
            if(uf.same(j,j+n)){
                res = 0;
            }else{
                res *=2;
            }
            p[uf.find(j)] = 1;
        }
        ans += res;
        // cerr << bit << " " << res << endl;
    }
    cout << ans << endl;
    return 0;
}
#include<iostream>
#include<vector>
using namespace std;
int N,M;
vector<int>G[20];
int col[20];
bool dfs(int u) {
	for(int v:G[u]) {
		if(col[v]==-1) {
			col[v]=3-col[u];
			if(!dfs(v))return false;
		}
		else if(col[u]==col[v])	{
			return false;
		}
	}
	return true;
}

int main() {
	cin>>N>>M;
	vector<pair<int,int> >E(M);
	for(int i=0;i<M;i++) {
		int a,b;cin>>a>>b;
		a--,b--;
		E[i]=make_pair(a,b);
		G[a].push_back(b);
		G[b].push_back(a);
	}

	long ans=0;
	for(int k=0;k<1<<N;k++)	{
		for(int i=0;i<N;i++) {
			col[i]=-1;
			if(k>>i&1)col[i]=0;
		}
		bool ok=true;
		for(pair<int,int>e:E)if(col[e.first]==0&&col[e.second]==0) {
			ok=false;
			break;
		}
		if(!ok)continue;
		int cnt=0;
		for(int i=0;i<N;i++)if(col[i]==-1)	{
			col[i]=1;
			if(!dfs(i))
			{
				ok=false;
				break;
			}
			cnt++;
		}
		if(ok)ans+=1<<cnt;
	}
	cout<<ans<<endl;
}
