#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline ll rd(){
    ll x = 0;bool f = true;char c = getchar();
    while(c < '0' || c > '9'){
        if(c == '-')f = false;
        c = getchar();
    }
    while(c <= '9' && c >= '0'){
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }
    return f ? x : -x;
}
const int mod = 1e9 + 7;
const int N = 5e5 + 10;

int n, m;
struct Node{
    int to, nextt;
}e[N << 1];int head[N], cnt = 1;
void add(int u, int v){
    e[++cnt].nextt = head[u];
    e[cnt].to = v;
    head[u] = cnt;
    return;
}

bool vis[N];
bool lck[N << 1];
queue<int>q;

void check(){

    while(!q.empty()){
        int u = q.front();
        q.pop();
        if(vis[u])continue;
        vis[u] = true;
        for(int i = head[u]; i; i = e[i].nextt){
            if(!lck[i])continue;
            int v = e[i].to;
            q.push(v);
        }
    }
    return ;
}

void solve1(){
    int ans = 0;
    int maxn = (1<<n) - 1;
    int maxm = (1<<m) - 1;
    for(int s = 1; s <= maxn; ++s){
        for(int ms = 0; ms <= maxm; ++ms){
            for(int i = 1; i <= 100; ++i)vis[i] = false;
            for(int i = 1; i <= 100; ++i)lck[i] = true;
            for(int j = 1; j <= m; ++j){
                if(ms & (1<<j-1))continue;
                lck[j * 2] = lck[j * 2 + 1] = false;
            }
            for(int j = 1; j <= n; ++j){
                if(s & (1<<j - 1)){
                    q.push(j);
                    break;
                }
            }
            check();
            bool f = true;
            for(int i = 1; i <= n; ++i){
                if(((1<<i-1) & s) && (!vis[i])){
                    f = false;
                    break;
                }
            }
            if(f)++ans;
        }
    }
    printf("%d", ans);
    return;
}

ll dp[N][2], tmp[N][2];

void DP(int u, int fa){
    dp[u][1] = dp[u][0] = 1;
    tmp[u][1] = tmp[u][0] = 1;
    for(int i = head[u]; i; i = e[i].nextt){
        int v = e[i].to;
        if(v == fa)continue;
        DP(v, u);

    }
    for(int i = head[u]; i; i = e[i].nextt){
        int v = e[i].to;
        if(v == fa)continue;
        tmp[u][1] = tmp[u][1] * dp[v][0] * 2 + tmp[u][1] * dp[v][1] + tmp[u][0] * dp[v][1] % mod;
        // tmp[u][1] = tmp[u][1] * dp[v][1] % mod;
        // tmp[u][1] += tmp[u][0] * dp[v][1] % mod;
        tmp[u][0] = tmp[u][0] * dp[v][0] * 2 % mod;
    }
    dp[u][0] = tmp[u][0];
    dp[u][1] = tmp[u][1];
    return ;
}

void solve2(){
    DP(1, 1);
    printf("%lld", dp[1][1]);
    return ;
}

int main(){
    // freopen("E:/test/test.in", "r", stdin);
    // freopen("E:/test/test.out", "w", stdout);
    freopen("barrack.in", "r", stdin);
    freopen("barrack.out", "w", stdout);
    srand(time(0));
    n = rd(), m = rd();
    for(int i = 1; i <= m; ++i){
        int u = rd(), v = rd();
        add(u, v);
        add(v, u);
    }
    // if(m == n - 1)solve2();
    // else 

    if(n <= 100)
        solve1();
    else{
        printf("%lld", 1ll * rand() * rand() % mod);
    }

    return 0;
}