// #include<iostream>
// #include<bits/stdc++.h>
// #include<vector>
// #include<algorithm>
// #include<string>
// #include<cmath>
// #include<iomanip>
// #include<numeric>
// #include<set>
// // #include<pair>
// #include<cctype>


 


/**** BE SPECIFIC WITH YOUR GOAL ******/
/**** TRY TO DRY RUN YOUR CODE AS YOU CAN ****/

#include<bits/stdc++.h>
#include<iostream>

using namespace std;

#define rep(i,a,b) for(int i=a; i<b; i++)
#define repp(i,a,b) for(int i=a; i>=b; i--)

#define ll long long

#define mp make_pair
#define pb push_back
#define F first
#define S second
#define vi vector<ll>
#define vpi vector<pair<ll,ll>>
#define all(x) x.begin(),x.end()
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define setpre cout<<fixed<<setprecision(10)
#define sumv(a) accumulate(all(a),0)
#define lb lower_bound
#define ub upper_bound
#define mod 1000000007
#define INF 1000000000000000000LL
#define PI 3.14159265358979 


const int N = 1000005;
ll modd = 998244353;
vector<bool> isprime(N);
vector<int> primes;
void seive(){
    isprime[0]=false;
    isprime[1]=false;
    for(int i=2; i<=1e6; i++){
        isprime[i] = true;
    }
    for(int i=2; i*i<=1e6; i++){
        if(isprime[i]){
            for(int j=i*i; j<=1e6; j+=i){
                isprime[j]=false;
            }
        }
    }
    for(int i=2; i<1e6; i++){
        if(isprime[i]){
            primes.pb(i);
        }
    }
}
/*** START YOUR CODE USING ABOVE SHORTS ***/

vector<ll> v[25];
ll vis[25];
ll lvl[25];
ll col[25];
ll dfs(ll ind){
    ll ret = 1;
    vis[ind] = 0;
    for(ll x:v[ind]){
        if(lvl[x] != 0 && lvl[x] != lvl[ind]+1){
            if(col[x] == col[ind]){
                ret = 0;
            }
            continue;
        }
        lvl[x] = lvl[ind]+1;
        ll temp = 0;
        rep(i,1,4){
            if(i == col[ind]) continue;
            col[x] = i;
            temp += dfs(x);
            col[x] = 0;
        }
        ret *= temp;
    }
    return ret;
}
void Reverse_Matrix(){
    ll n,m; cin>>n>>m;
    // cout<<n<<" "<<m<<endl;
    rep(i,0,n+1){
        vis[i] = 1;
        lvl[i] = 0;
        col[i] = 0;
    }
    rep(i,0,m){
        int x,y; cin>>x>>y;
        v[x].pb(y);
        v[y].pb(x);
    }
    ll ans = 1;
    rep(i,1,n+1){
        if(vis[i]){
            lvl[i] = 1;
            col[i] = 1;
            ans *= 3 * dfs(i);
            // cout<<i<<" ";
        }
        // cout<<endl;
    }
    cout<<ans<<endl;
}

int main(){
    ios_base::sync_with_stdio(false);
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);
    // seive();
    int TEST = 1;
    
    // cin>>TEST;
    
    while(TEST--){
        Reverse_Matrix();
    }
}
#include<bits/stdc++.h>
using namespace std;

// @author: sharad_sharma

#define ll                long long
#define ld                long double
#define mod               1000000007
#define inf               1e18
#define pb                push_back
#define all(n)            n.begin(),n.end()
#define loop(i,a,b)       for(int i=(a);i<=(b);i++)
#define logarr(arr)       for(int z=(0);z<(arr.size());z++) cout<<(arr[z])<<" ";cout<<endl;
#define deb(x)            cout << #x << " = " << x << endl
#define debu(x, y)        cout << "( " << #x << ", " << #y << " ) = ( " << x << ", " << y << " )" << endl

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define int long long
void file_i_o()
{
    ios_base::sync_with_stdio(0); 
    cin.tie(0); 
    cout.tie(0);
	#ifndef ONLINE_JUDGE
	    freopen("input.txt", "r", stdin);
	    freopen("output.txt", "w", stdout);
	#endif
}

int N = 25;
vector<vector<int>> adj(N);
vector<int> visited(N, 0);
vector<int> col(N, 0);
vector<int> level(N, 0);

// i want to search exhaustively
int dfs(int i, int p) {
	//if(visited[i]) return 1;
	level[i] = level[p] + 1;
	visited[i] = 1;
	int ret = 1;

	for(auto u: adj[i]) {
		//if(u == p) continue;	// this is not enough if their level is same then it must return 0
		if(level[u] != 0 && level[u] != level[i] + 1) {
			if(col[u] == col[i]) {
				// this should not be allowed
				return 0;
			}	
			continue;
		}
	
		int tem = 0;
		for(int c=1; c<4; c++) {
			if(col[i] == c) continue;
			col[u] = c;
			tem += dfs(u, i);
			col[u] = 0;
		}
		ret *= tem;
	}
	return ret;
}

int32_t main(int32_t argc, char const *argv[]) {
	clock_t begin = clock();
	file_i_o();

	// Write your code here....
	int n, m;
	cin >> n >> m;
	for(int i=0; i<m; i++) {
		int x, y;
		cin >> x >> y;
		x--; y--;
		adj[x].pb(y);
		adj[y].pb(x);
	}
	int ans = 1LL;

	for(int i=0; i<n; i++) {
		if(visited[i]) continue;
		// let's say we colour Red on i so, it's edges is either blue or green
		col[i] = 1;	// let's say Red is 1
		level[i] = 0;
		int dd = dfs(i, i);
		ans = ans*3LL*dd;
	}
	cout << ans << "\n";
	
	#ifndef ONLINE_JUDGE 
	  clock_t end = clock();
	  cout<<"\n\nExecuted In: "<<double(end - begin) / CLOCKS_PER_SEC*1000<<" ms";
	#endif 
	return 0;
}

