#include<bits/stdc++.h>
#define int long long
using namespace std;
struct edge{
	int to,next;
}e[10000];
int n,m,a[30],head[30],cnt,ans=1,res,t,b[30];
bool vis[30];
inline void add(int u,int v){
	cnt++;
	e[cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
inline void dfs1(int u){
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].to;
		if(vis[v])continue;
		vis[v]=1;
		b[++t]=v;
		dfs1(v);
	}
}
inline void dfs(int u,int s){
	bool tag[4],flag=0;
	memset(tag,0,sizeof(tag));
	int sum=0;
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].to;
		if(a[v]&&!tag[a[v]])tag[a[v]]=1,sum++;
	}
	if(sum==3)return;
	if(s==t){
		a[u]=0;
		for(int i=1;i<=3;i++)if(!tag[i])res++;
		return;
	}
	for(int j=1;j<=3;j++)
	if(!tag[j]){
		flag=0;
		a[u]=j;
		for(int i=head[u];i;i=e[i].next){
			int v=e[i].to;
			if(a[v])continue;
			flag=1;
			dfs(v,s+1);
			break;
		}
		if(!flag){
		    for(int i=1;i<=t;i++)
		    if(!a[b[i]]){
			    dfs(b[i],s+1);
			    break;
		    }
	    }
	}
	a[u]=0;
}
signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1,x,y;i<=m;i++){
		scanf("%lld%lld",&x,&y);
		add(x,y);
		add(y,x);
	}
	for(int i=1;i<=n;i++)
	if(!vis[i]){
		vis[i]=1;
		t=1;
		b[1]=i;
		dfs1(i);
		//cout<<t<<endl;
		res=0;
		dfs(i,1);
		ans*=res;
	}
	printf("%lld",ans);
	return 0;
}
#include <bits/stdc++.h>
#define int long long int
#define ll long long int
#define ld long double
#define getFaster ios_base::sync_with_stdio(false), cin.tie(nullptr)
#define rep(i, init, n) for (int i = init; i < (int)n; i++)
#define rev(i, n, init) for (int i = (int)n; i >= init; i--)
#define MOD1 1e9 + 7
#define MOD2 998244353
#define f first
#define s second
#define endl '\n'
#define pii pair<int, int>
#define tii tuple<int, int>
#define all(v) v.begin(), v.end()
#define mt make_tuple
#define precise(i) cout << fixed << setprecision(i)
#define codejam cout << "Case #" << ii + 1 << ": ";
#define impossible cout << "IMPOSSIBLE" << endl;
#define error(s) throw runtime_error(s)
#define hash hash1
std::mt19937_64 rng(std::chrono::steady_clock::now().time_since_epoch().count());
int myRand(int R)
{
     int val = rng() % R;
     assert(val >= 0);
     return val;
}

const long double PI = atan(1.0) * 4;
const int32_t INF32 = 2e9 + 7;
const int64_t INF64 = 3e18;
const int32_t LOG = 21;
int32_t MOD = MOD1;

using namespace std;

//-------------------DEBUGGING-------------------------
void my_debugger(string s, int LINE_NUM) { cerr << endl; }
template <typename start, typename... end>
void my_debugger(string s, int LINE_NUM, start x, end... y)
{
     if (s.back() != ',')
     {
          s += ',';
          cerr << "LINE(" << LINE_NUM << "): ";
     }
     int i = s.find(',');
     cerr << s.substr(0, i) << " = " << x;
     s = s.substr(i + 1);
     if (!s.empty())
          cerr << ", ";
     my_debugger(s, LINE_NUM, y...);
}

#ifdef AJIT
#define debug(...) my_debugger(#__VA_ARGS__, __LINE__, __VA_ARGS__);
#else
#define debug(...) ;
#endif

void setMod(int mod_val)
{
     MOD = mod_val;
}
//-----------------------------------------------------

void files_init()
{
     freopen("maxflow.in", "r", stdin);
     freopen("maxflow.out", "w", stdout);
}

const int N = 1e5 + 5;
const int LOGN = 20;

vector<int> v[25];
vector<pii> edges;
bool check[25];
int color[25];
bool g=true;

void dfs(int i,int col=0)
{
    if(!g)return;
    debug(i,col);
    color[i]=col;
    check[i]=true;
    for(auto it:v[i])
    {
         if(check[it] && color[it]==col)
         {
              g=false;
              return;
         }
         else if(!check[it])
         dfs(it,col^1);
    }
}


int32_t main()
{
     getFaster;
     //files_init();
     int tests = 1;
     //cin >> tests;
     rep(ii, 0, tests)
     {
          int n,m;
          cin>>n>>m;
          rep(i,0,m)
          {
               int x,y;
               cin>>x>>y;
               x--,y--;
               edges.push_back({x,y});
               v[x].push_back(y);
               v[y].push_back(x);
          }

          int ans=0;
          rep(mask,0,(1<<n))
          {
               fill(check,check+n,false);
               fill(color,color+n,0);
               rep(i,0,n)v[i].clear();
               g=true;
               debug("HELLO");
               for(auto& it:edges)
               {
                   int x=it.f,y=it.s;
                   if( ((1<<x)&mask) && ((1<<y)&mask))
                   {
                        g=false;
                        break;
                   }
                   else if( !((1<<x)&mask) && !((1<<y)&mask) )
                   {
                        v[x].push_back(y);
                        v[y].push_back(x);
                   }
               }

               debug("EDGES ADDED");

               if(!g)continue;
               int temp=1;
               
               rep(i,0,n)
               if(!check[i] && !((1<<i) & mask))
               {
                    debug("DFS FROM I=",i)
                    dfs(i);
                    temp*=2;
                    if(!g)
                    break;
               }

               if(g)
               ans+=temp;
          } 

          cout<<ans<<endl;
     }
     return 0;
}