#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#include<unordered_map> 
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define fio ios_base::sync_with_stdio(false)
#define li long long int  
#define ll long long int 
//#define readi(x) scanf("%lld",&x)
#define  reads(x)  scanf("%s", x)
#define readl(x) scanf("%lld",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 100000000000000005
#define MINN -10000000000000000
#define INTMAX 1000001000
#define pii pair<li,li> 
#define pdd pair<double,double>
#define pic pair<int,char>
//#define N 5005
#define lgn 20
#define ddouble long double
#define minus minu
#define PI 3.1415926535
#define lgn 20
using namespace std;
//li bit[200004]={0};
li mod=1000000007;
li mod2=998244353;
 
/*
void update(li x,li n,li val){//cout<<(x-1)<<" "<<val<<endl;
    while(x<=n){bit[x]+=val;x=x+((-x)&x);}}
 
li query(li x,li n){li c=0;while(x>0){c+=bit[x];x=x-((-x)&x);}return(c);}
 
li pp(li a,li b,li modd){
    if(b==0) return(1);
    li ans=pp(a,b/2,modd);ans=(ans*ans)%modd;if(b%2) ans=(ans*a)%modd;return(ans);
}
*/
li gcd(li a,li b){
    if(a<b) return(gcd(b,a));
    if(b==0) return(a);
    return(gcd(b,a%b));
}
 
vector<li> z_function(string s)
{
     li n=s.size();
     vector<li>z(n);
     for(li i=1,l=0,r=0;i<n;i++)
     {
         if(i<=r)
         {
             z[i]=min(r-i+1,z[i-l]);
         }
         while((i+z[i])<n && s[z[i]]==s[i+z[i]]){++z[i];}
         if((i+z[i]-1)>r){l=i;r=i+z[i]-1;}
     }
     return(z);    
}
 
/*vector<li>p(2005,0);
li parent(li a){
    if(p[a]==0 || p[a]==a){p[a]=a;return(a);}
    return(p[a]=parent(p[a]));
}
void unionn(li a,li b){p[a]=b;}*/
/*vector<pii>MM;li N;*/
/*li ff(li i,li j,vector<vector<li>>& dp)
{
    if(i==0 && j==0)
    {
        return(1);
    }
    if(dp[i][j]!=-1) return(dp[i][j]);
    li ans=0;
    if(i)
    {
        ans+=ff(i-1,j,dp);
    }
    if(j)
    {
        ans+=ff(i,j-1,dp);
    }
    dp[i][j]=ans;
    return(ans);
}*/
 
li DFS(li i,li p,vector<vector<li>>& M,vector<li>& D,vector<li>& C)
{
    if(p==0) D[i]=1;
    else D[i]=D[p]+1;
    li ans=0,y=1;
    for(li c=0;c<3;c++)
    {
        if(p!=0 && C[p]==c) continue;
        C[i]=c;
        y=1;
        for(auto x:M[i])
        {
            if(x!=p)
            {
                if(D[x]==-1 || D[x]==(D[i]+1))
                {
                    y=y*(DFS(x,i,M,D,C));   
                }
                else if(D[x]<D[i])
                {
                    if(C[i]==C[x]) {y=0;break;}
                }  
            }
        }
        //C[i]=-1;
        //if(i==1) cout<<y<<" "<<c<<endl;
        ans=ans+y;
    }
    return(ans);
}
 
 
int main()
{
li i,j,a,b,c,d,g,h,k,m,n,q,s,t,x,y,z,X,Y,sz,st,end,mid,ans,W,pa,pb,l,r,p,M;
    string T,SN,S,TN;
    //char S1[100004];
    
    n=1000005;
    /*vector<li>v(n+2,0);
    for(i=2;i<=n;i++)
    {
        if(v[i]==0)
        {
            for(j=i;j<=n;j+=i)
            {
                v[j]=i;
            }
            //cout<<v[i]<<" ";
        }
    }*/
    t=1;
    //readl(t);
    x=0;
    while(t--)
    {  
        readl(n);readl(m);
        vector<vector<li>>M(n+2);
        vector<li>D(n+2,-1);
        vector<li>C(n+2,-1);
        for(i=0;i<m;i++)
        {
            readl(a);readl(b);
            M[a].pb(b);
            M[b].pb(a);
        }
        ans=1;
        for(i=1;i<=n;i++)
        {
            //cout<<D[i]<<endl;
            if(D[i]==-1)
            {
                //cout<<i<<endl;
                ans=ans*DFS(i,0,M,D,C);
            }
        }
        cout<<ans<<endl;
        //return(0);
        //x++;   
        //cout<<"Case #"<<x<<": "<<    
    }
}
///Given threee color R,G,B .Now find the number of ways of coloring the n nodes and m edges graph using these color
///where no adjacent nodes can be same color
///Here n<=10
///Idea : As n<=10 so ideal backtracking can be done complexity:3*(2^10)

#include<bits/stdc++.h>
using namespace std;
#define   ll long long int
#define pb push_back
ll lvl[21];
ll color[21];
vector<ll>adj[21];
vector<ll>vis(21,0);
ll solve(ll src)
{
    vis[src]=1;
    ll ret=1;
        for(auto x:adj[src])
        {
            if(lvl[x]!=0&&lvl[x]!=lvl[src]+1)
            {
                if(color[src]==color[x])
                {
                  ret=0;
                }
                continue;
            }

            if(lvl[x]==0)
            lvl[x]=lvl[src]+1;
            ll tot=0;
            for(ll i=1;i<=3;i++)
            {
                if(i==color[src])
                    continue;

                color[x]=i;
                tot+=solve(x);
                color[x]=0;
            }
            ret=ret*tot;
     }

   return ret;

}
int main()
{
  ll n,m;
  cin>>n>>m;

  for(ll i=0;i<m;i++)
  {
      ll u,v;
      cin>>u>>v;
      adj[u].pb(v);
      adj[v].pb(u);
  }

ll ans=1;

for(ll i=1;i<=n;i++)
{
    if(vis[i])
        continue;
    lvl[i]=1;
    color[i]=1;
    ans=3*ans*solve(i);
}

cout<<ans;

return 0;
}
