#ifdef MY_LOCAL
#define MY_NAMESPACE(ns) namespace ns {
#define MY_NAMESPACE_    }
#define MY_DEBUG(s)      s
#define MY_IS_DEBUG      (true)
#else
#define MY_NAMESPACE(ns) 
#define MY_NAMESPACE_    
#define MY_DEBUG(s)
#define MY_IS_DEBUG      (false)
#endif

#include <algorithm>
#include <bitset>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<int, ll> pil;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;

constexpr int IMIN = numeric_limits<int>::min();
constexpr int IMAX = numeric_limits<int>::max();
constexpr ll LLMIN = numeric_limits<ll>::min();
constexpr ll LLMAX = numeric_limits<ll>::max();

template <typename T> bool chmax(T& maxval, T const& newval) { if (newval > maxval) { maxval = newval; return true; } return false; }
template <typename T> bool chmin(T& minval, T const& newval) { if (newval < minval) { minval = newval; return true; } return false; }


MY_NAMESPACE(testbed)
void dfs_route(int this_v, vector<vector<int>> const& edges, vector<int>& route, vector<int>& visited)
{
	route.push_back(this_v);
	visited[this_v] = route.size() - 1;

	for (int i = 0; i < (int)edges[this_v].size(); i++)
	{
		int next_v = edges[this_v][i];
		if (visited[next_v] != IMAX)
			continue;
		dfs_route(next_v, edges, route, visited);
	}
}

ll dfs(int this_i, vector<vector<int>> const& edges, vector<int> const& route, vector<int>& colours)
{
	int this_v = route[this_i];
	int this_colour = colours[this_v];

	for (int i = 0; i < (int)edges[this_v].size(); i++)
	{
		int test_v = edges[this_v][i];
		int test_colour = colours[test_v];
		if (test_colour == this_colour)
			return 0;
	}

	int next_i = this_i + 1;
	if (next_i == route.size())
		return 1;
	int next_v = route[next_i];

	ll ans = 0;
	colours[next_v] = 0;
	ans += dfs(next_i, edges, route, colours);
	colours[next_v] = 1;
	ans += dfs(next_i, edges, route, colours);
	colours[next_v] = 2;
	ans += dfs(next_i, edges, route, colours);
	colours[next_v] = IMAX;

	return ans;
}

int main()
{
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	int n, m;
	cin >> n >> m;

	vector<vector<int>> edges(n);
	for (int i = 0; i < m; i++)
	{
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		edges[a].push_back(b);
		edges[b].push_back(a);
	}

	ll ans = 1;
	vector<int> visited(n, IMAX);
	vector<int> colours(n, IMAX);
	for (int v = 0; v < n; v++)
	{
		if (visited[v] == IMAX)
		{
			vector<int> route;
			dfs_route(v, edges, route, visited);
			colours[v] = 0;
			ll this_ans = dfs(0, edges, route, colours);
			this_ans *= 3;
			ans *= this_ans;
		}
	}
	cout << ans << "\n";
	return 0;
}
MY_NAMESPACE_

#include <cstdio>
#include <cmath>
#include <iostream>
#include <set>
#include <algorithm>
#include <vector>
#include <map>
#include <cassert>
#include <string>
#include <cstring>
#include <queue>

using namespace std;

#define rep(i,a,b) for(int i = a; i < b; i++)
#define S(x) scanf("%d",&x)
#define S2(x,y) scanf("%d%d",&x,&y)
#define P(x) printf("%d\n",x)
#define all(v) v.begin(),v.end()
#define FF first
#define SS second
#define pb push_back
#define mp make_pair

typedef long long int LL;
typedef pair<int, int > pii;
typedef vector<int > vi;

const int N = 20;

int G[N][N];
int n;
int col[N];

int bit(int mask, int x) {
  return (mask >> x) & 1;
}

bool singlecol(int mask) {
  rep(i,0,n) if(bit(mask, i)) {
    rep(j,i+1,n) if(bit(mask, j)) {
      if(G[i][j]) return false;
    }
  }
  return true;
}

bool dfs(int c, int mask, int cc) {
  if(col[c] != -1) {
    return col[c] == cc;
  }
  col[c] = cc;
  bool res = true;
  rep(i,0,n) if(bit(mask, i) && G[c][i]) {
    res &= dfs(i, mask, cc ^ 1);
  }
  return res;
}

LL twocol(int mask) {
  memset(col, -1, sizeof(col));
  LL res = 1;
  rep(i,0,n) if(bit(mask, i) && col[i] == -1) {
    if(!dfs(i, mask, 0)) {
      res = 0;
    } else {
      res *= 2;
    }
  }
  return res;
}

int main() {
  int m;
  S2(n,m);
  rep(i,0,m) {
    int x,y;
    S2(x,y);
    x--; y--;
    G[x][y] = G[y][x] = 1;
  }
  int mx = (1 << n) - 1;
  LL ans = 0;
  rep(i,0,1<<n) {
    if(!(i & 1)) continue;
    if(singlecol(i)) {
      ans += twocol((~i) & mx);
      // printf("%d %lld\n",i,ans);
    }
  }
  ans *= 3;
  cout << ans << "\n";
  return 0;
}
