// D - RGB Coloring 2
// sample code
// reference: https://atcoder.jp/contests/abc199/submissions/22053625
#include <bits/stdc++.h>
using namespace std;
#define vec vector
using vi = vec<int>;
using ll = int64_t;
#define rep(i,e) for(int i=0;i<(e);++i)

vec<vi> G(20); // 隣接リスト
vi used(20, -1); // 彩色順（連結成分ごとに採番）
vi colors(20, -1); // 彩色された点

ll dfs(int now){
	ll res = 0;
	for(int to:G[now]) if(colors[to] == colors[now]) return res; // 隣接色かぶり
	res = 1;
	for(int to:G[now]){ // 隣接点
		if(used[to] == -1) used[to] = used[now] + 1; // 未訪問->彩色順を採番
		if(used[to] != used[now] + 1) continue; // 彩色順どおりでない->訪問済み
		ll tmp = 0;
		rep(i, 2){ // colors[now] で使っていない 2 色で再帰
			colors[to] = (colors[now] + i+1) % 3; // 隣接点を彩色
			tmp += dfs(to); // 隣接点へ
		}
		colors[to] = -1; // 無色に戻す
		res *= tmp;
		if(res == 0) break; // used が採番しきれていない点に注意
	}
 	return res;
}

int main(){
	int n, m; cin>>n>>m;
	rep(i, m){
		int a, b; cin>>a>>b; --a, --b;
		G[a].push_back(b);
		G[b].push_back(a);
	}

	ll ans = 1;
	rep(i, n){
		if(used[i] != -1) continue; // 採番済み->訪問済み
		used[i] = colors[i] = 0; // 開始点の訪問済み＆彩色
		ans *= dfs(i) * 3;
	}
	cout<< ans <<endl;
}

#include <bits/stdc++.h>
#include <sys/time.h>
#pragma GCC optimize "O3,omit-frame-pointer,inline"
#define REP(i, n) for(int i = 0;i < n;i++)
#define ll long long
using namespace std;
//typedef vector<unsigned int>vec;
//typedef vector<ll>vec;
//typedef vector<vec> mat;
typedef pair<int, int> P;
typedef pair<ll,ll> LP;
//const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
//const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
const int INF = 1000000000;
const ll LINF = 1000000000000000000;//1e18
const ll  MOD = 1000000007;
const double PI = acos(-1.0);
const double EPS = 1e-10;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
//template<class T> inline void add(T &a, T b){a = ((a+b) % MOD + MOD) % MOD;};


constexpr ll CYCLES_PER_SEC = 2800000000;
constexpr double TL = 1990;
double get_ms() { struct timeval t; gettimeofday(&t, NULL); return (double)t.tv_sec * 1000 + (double)t.tv_usec / 1000; }
constexpr int dh[4] = {-1, 0, 1, 0};
constexpr int dw[4] = {0, 1, 0, -1};
constexpr char MOVE[4] = {'U', 'R', 'D', 'L'};

uint32_t XorShift(void) {
	static uint32_t x = 123456789;
	static uint32_t y = 362436069;
	static uint32_t z = 521288629;
	static uint32_t w = 88675123;
	uint32_t t;

	t = x ^ (x << 11);
	x = y; y = z; z = w;
	return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
}

double Prob(void){
	double ret = (double)XorShift() / UINT_MAX;
	return ret;
}


namespace AHC004{
    int N, M;
    vector<string> S;
    void input(){
        cin >> N >> M;
        S.resize(M);
        REP(i,M) cin >> S[i];
    }


    void output(){
        REP(i,N) cout << string(N, 'A') << endl;
    }

    void main(){
        input();
        output();
    }
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    AHC004::main();
}