#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define all(a) a.begin(),a.end()
typedef pair<ll,ll> pi;

//__builtin_popcountll(2) (the number of ones in the binary representation)
//__builtin_clz(2) (number of leading zeroes)
//__builtin_ctz(2) (number of trailing zeroes)

/*#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
using namespace __gnu_pbds; 
  
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>*/
// s.find_by_order(k)(returns iterator to kth element), s.order_of_key(k)(number of elements less than number)

ll mod = 1e9+7;
vector<ll> fact(1);
/*vector<ll> spf(10000005), cntPrime(10000005);

void spff(){
    int i;
    for(i=1;i<10000005;i++) spf[i] = i;
    for(i=2;i*i<10000005;i++)
    {
        if(spf[i] != i) continue;
        for(int j = i*i; j < 10000005; j+= i){
            if(spf[j]==j) spf[j] = i;
        }
    }
    for(i=1;i<10000005;i++){
        if(spf[i] != spf[i/spf[i]]){
            cntPrime[i] = cntPrime[i/spf[i]]+1;
        }
        else cntPrime[i] = cntPrime[i/spf[i]];
    }
}
while(spf[a[i]]!=a[i]){
              z=spf[a[i]];
              while(a[i]%z==0) a[i]/=z;
              m[z]++;
          }
          if(a[i]>1) m[a[i]]++;*/
 
ll gcd(ll a, ll b) 
{ 
    if (b == 0) 
        return a; 
    return gcd(b, a % b);       
}
 
ll power(ll x, ll y) 
{ 
    ll temp; 
    if( y == 0) 
        return 1; 
    temp = power(x, y/2); 
    if (y%2 == 0) 
        return temp*temp; 
    else
        return x*temp*temp; 
}
 
ll power(ll x, ll y, ll p) 
{ 
    ll res = 1; 
    x = x % p; 
  
    while (y > 0) { 
        if (y & 1) res = (res * x) % p; 
        y = y >> 1;
        x = (x * x) % p; 
    } 
    return res; 
} 
  
ll modInv(ll n, ll p) 
{ 
    return power(n, p - 2, p); 
} 
 
ll ncr(ll n, ll r) {return (n>=r?(fact[n]*modInv(fact[r],mod))%mod*modInv(fact[n-r],mod)%mod:0);}

ll add(ll a, ll b) {ll z=a+b; if(z>=mod) z -= mod; return z;}
ll sub(ll a, ll b) { return (a-b+mod)%mod;}
// LLONG_MAX

vector<ll> v[25], vis(25), ver;
ll z;

void dfs(ll x){
    vis[x]=1;
    ver.pb(x);
    for(auto i: v[x]){
        if(vis[i]) continue;
        dfs(i);
    }
}

void solve(ll idx, vector<ll>& col){
    if(idx == ver.size()){
        z++; return;
    }
    vector<ll> a{1,2,3};
    for(auto i: v[ver[idx]]){
        if(find(all(a),col[i]) != a.end()) a.erase(find(all(a),col[i]));
    }

    for(auto i: a){
        col[ver[idx]] = i;
        solve(idx+1, col);
    }
    col[ver[idx]] = 0;
}

int main()
{  
  ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
  ll t=1,n,i,j,m,a,b;
  //cin>>t;
  //fact[0]=1;
  //for(i=1;i<300003;i++)fact[i]=(fact[i-1]*i)%mod;
  while(t--)
  {
      cin>>n>>m;
      for(i=0;i<m;i++){
          cin>>a>>b;
          v[a].pb(b);
          v[b].pb(a);
      }
      ll ans=1;
      for(i=1;i<=n;i++){
          ver.clear();
          if(!vis[i]){
              z=0;
              dfs(i);
              vector<ll> col(n+2);
              solve(0, col);
              ans*=z;
          }
      }
      cout<<ans;
  }
}

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

void dfs(const int64_t s, const vector<vector<int>>& g,
         vector<bool>& v, vector<int>& p) {
    if (v[s]) return;
    p.push_back(s), v[s] = true;
    for (auto i = 0; i < (int)g[s].size(); i++)
        if (g[s][i] == 1) dfs(i, g, v, p);
}

void dfs2(const int64_t s, const vector<vector<int>>& g,
          const vector<int>& p, vector<int>& color,
          int64_t& ans) {
    if (s == (int)p.size()) {
        ans++;
        return;
    }
    bool b[3] = {};
    for (auto i = 0; i < s; i++) {
        if (not g[p[i]][p[s]]) continue;
        b[color[i]] = 1;
    }
    for (auto i = 0; i < 3; i++)
        if (not b[i]) {
            color[s] = i;
            dfs2(s + 1, g, p, color, ans);
            color[s] = -1;
        }
}

int main() {
    int64_t n, m, ans = 1;
    cin >> n >> m;
    vector<vector<int>> g(n, vector<int>(n, 0));
    vector<bool> v(n, false);
    for (auto i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b, a--, b--;
        g[a][b] = 1, g[b][a] = 1;
    }
    for (auto i = 0; i < n; i++) {
        if (v[i]) continue;
        vector<int> p, c;
        dfs(i, g, v, p);
        c.assign(p.size(), -1);
        int64_t cnt = 0;
        c[0] = 1;
        dfs2(1, g, p, c, cnt);
        ans *= (cnt * 3);
    }
    cout << ans << endl;
    return 0;
}