#include <bits/stdc++.h>   #pragma GCC optimize( O3 )   using namespace std;   int n, m;   const int maxN = 42;   vector<int> g[maxN];   int deg[maxN];   bool ed[maxN][maxN];   long long f() { return (1LL << n); }   const int maxK = 20;   bool bad[(1 << maxK) + 10];   int from[(1 << maxK) + 10];   bool other_bad[(1 << maxK) + 10];   int cnt[(1 << maxK) + 10];   long long indep() {     int half = n / 2;     for (int i = 0; i < half; i++) {       for (int j = i + 1; j < half; j++) {         if (ed[i][j]) {           bad[(1 << i) + (1 << j)] = true;         }       }       for (int j = half; j < n; j++) {         if (ed[i][j]) {           from[(1 << i)] |= (1 << (j - half));         }       }     }     for (int bit = 0; bit < half; bit++) {       for (int mask = 0; mask < (1 << half); mask++) {         if (mask & (1 << bit)) {           bad[mask] |= bad[mask ^ (1 << bit)];           from[mask] |= from[mask ^ (1 << bit)];         }       }     }     int other_half = n - half;     for (int i = half; i < n; i++) {       for (int j = i + 1; j < n; j++) {         if (ed[i][j]) {           other_bad[(1 << (i - half)) + (1 << (j - half))] = true;         }       }     }     for (int bit = 0; bit < other_half; bit++) {       for (int mask = 0; mask < (1 << other_half); mask++) {         if (mask & (1 << bit)) {           other_bad[mask] |= other_bad[mask ^ (1 << bit)];         }       }     }     for (int mask = 0; mask < (1 << other_half); mask++) {       if (!other_bad[mask]) cnt[mask] = 1;     }     for (int bit = 0; bit < other_half; bit++) {       for (int mask = 0; mask < (1 << other_half); mask++) {         if (mask & (1 << bit)) {           cnt[mask] += cnt[mask ^ (1 << bit)];         }       }     }     int all = (1 << other_half) - 1;     long long tot = 0;     for (int my_mask = 0; my_mask < (1 << half); my_mask++) {       if (bad[my_mask]) continue;       int bad_guys = from[my_mask];       int good_guys = all ^ bad_guys;       tot += cnt[good_guys];     }     return tot;   }   bool used[maxN];   void dfs(int v) {     used[v] = true;     for (int to : g[v]) {       if (used[to]) continue;       dfs(to);     }   }   long long ones() {     int tot = 0;     memset(used, 0, sizeof used);     for (int i = 0; i < n; i++) {       if (!used[i]) {         dfs(i);         tot++;       }     }     return (1LL << tot);   }   long long f01() {     int tot = 0;     for (int i = 0; i < n; i++)       if (deg[i] == 0) tot++;     return (1LL << tot);   }   int clr[maxN];   bool ALL_OK = true;   void other_dfs(int v) {     used[v] = true;     for (int to : g[v]) {       if (used[to]) {         if (clr[to] != clr[v] ^ 1) {           ALL_OK = false;           return;         }       } else {         clr[to] = clr[v] ^ 1;         other_dfs(to);       }     }   }   long long f02() {     int tot = 0;     memset(used, 0, sizeof used);     for (int i = 0; i < n; i++) {       if (!used[i]) {         tot++;         other_dfs(i);       }     }     if (!ALL_OK) return 0;     return (1LL << tot);   }   int main() {     ios_base::sync_with_stdio(false);     cin.tie(nullptr);     cin >> n >> m;     if (m == 0) {       cout << 0;       return 0;     }     for (int i = 0; i < m; i++) {       int a, b;       cin >> a >> b;       a--;       b--;       deg[a]++;       deg[b]++;       g[a].push_back(b);       g[b].push_back(a);       ed[a][b] = ed[b][a] = true;     }     long long x = f();     long long y = indep();     long long z = ones();     long long t = f01();     long long q = f02();     cout << x - 2 * y - z + 2 * t + q;     return 0;   }