#pragma GCC optimize("Ofast") 
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define sz(a) (int)(a.size())
#define all(a) a.begin(),a.end()
#define lb lower_bound
#define ub upper_bound
#define owo ios_base::sync_with_stdio(0);cin.tie(0);
#define MOD (ll)(998244353)
#define INF (ll)(1e18)
#define debug(...) fprintf(stderr, __VA_ARGS__),fflush(stderr)
#define time__(d) for(long blockTime = 0; (blockTime == 0 ? (blockTime=clock()) != 0 : false);\
debug("%s time : %.4fs\n", d, (double)(clock() - blockTime) / CLOCKS_PER_SEC))
typedef long long int ll;
typedef long double ld;
typedef pair<ll,ll> PII;
typedef pair<int,int> pii;
typedef vector<vector<int>> vii;
typedef vector<vector<ll>> VII;
ll gcd(ll a,ll b){if(!b)return a;else return gcd(b,a%b);}
vii adj(30);
vector<bool>vis(30);
int n,m;
vector<int>comp;
void get(int v){
	comp.pb(v);
	vis[v] = 1;
	for(int x:adj[v]){
		if(!vis[x])get(x);
	}
}
ll cnt = 0;
ll ans = 1;
void re(int cur,vector<int>comp,vector<int>color){
	if(cur == sz(comp)){
		cnt++;
		return;
	}
	vector<bool>a(4,0);
	int v = comp[cur];
	for(int x:adj[v]){
		a[color[x]] = 1;
	}
	for(int i=1;i<=3;i++){
		if(!a[i]){
			color[v] = i;
			re(cur+1,comp,color);
		}
	}
	
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<m;i++){
		int v,u;
		cin>>v>>u;
		adj[v].pb(u);
		adj[u].pb(v);
	}
	for(int i=1;i<=n;i++){
		if(!vis[i]){
			cnt = 0;
			comp.clear();
			get(i);
			//for(int x:comp)cout<<x<<" ";
			//cout<<'\n';
			vector<int>color(30);
			re(0,comp,color);
			ans*=cnt;
		}
	}
	cout<<ans;
	
}

#include <bits/stdc++.h>
using namespace std;

int main()
{
  int N, M, A, B;
  cin >> N >> M;
  vector<vector<int>> graph(N);
  for (int i = 0; i < M; i++)
  {
    cin >> A >> B;
    A--, B--;
    graph.at(A).push_back(B);
    graph.at(B).push_back(A);
  }
  vector<bool> checked(N,false);
  vector<int> colors(N,-1), blank(N,-1);
  pair<queue<int>, vector<int>> now_state;
  queue<pair<queue<int>, vector<int>>> big_que;
  queue<int> que;
  int now_node;
  bool is_OK;
  long long ans = 0, tmp_ans;
  for (int i = 0; i < N; i++)
  {
    if (checked.at(i))
      continue;
    colors = blank;
    colors.at(i) = 0;
    que.push(i);
    big_que.push(make_pair(que,colors));
    que.pop();
    checked.at(i) = true;
    tmp_ans = 0;
    while (!big_que.empty())
    {
      now_state = big_que.front();
      big_que.pop();
      is_OK = true;
      while (!now_state.first.empty())
      {
        now_node = now_state.first.front();
        for (int j = 0; j < graph.at(now_node).size(); j++)
        {
          if (now_state.second.at(graph.at(now_node).at(j)) == now_state.second.at(now_node))
          {
            is_OK = false;
            break;
          }
        }
        if (!is_OK) break;
        for (int j = 0; j < graph.at(now_node).size(); j++)
        {
          if (now_state.second.at(graph.at(now_node).at(j)) >= 0)
            continue;
          now_state.second.at(graph.at(now_node).at(j)) = (now_state.second.at(now_node)+1)%3;
          now_state.first.push(graph.at(now_node).at(j));
          big_que.push(now_state);
          now_state.second.at(graph.at(now_node).at(j)) = (now_state.second.at(now_node)+2)%3;
          checked.at(graph.at(now_node).at(j)) = true;
        }
        now_state.first.pop();
      }
      if (is_OK)
        tmp_ans++;
    }
    tmp_ans *= 3;
    if (ans)
      ans *= tmp_ans;
    else
      ans += tmp_ans;
  }
  cout << ans << endl;
}

