#include <bits/stdc++.h>
using namespace std;

namespace IO {
inline int read() {
    int x = 0, f = 0;
    char ch = getchar();
    while (!isdigit(ch)) f |= ch == '-', ch = getchar();
    while (isdigit(ch)) x = 10 * x + ch - '0', ch = getchar();
    return f ? -x : x;
}
template<typename T>
inline void write(T x) {
    static int stk[65], top;
    top = 0;
    if (x < 0) putchar('-'), x = -x;
    do {
        stk[++top] = x % 10;
        x /= 10;
    } while (x);
    while (top) {
        putchar(stk[top] + '0');
        top--;
    }
}
template<typename T>
inline void write(T x, char ch) {
    write(x), putchar(ch);
}
}

const int N = 100005;
const int mod = 1e9 + 7;

int fac[N], ifac[N];
inline int qpow(int a, int b = mod - 2) {
    int res = 1;
    while (b) {
        if (b & 1) res = 1ll * res * a % mod;
        a = 1ll * a * a % mod;
        b >>= 1;
    }
    return res;
}
void init(int n) {
    fac[0] = 1;
    for (int i = 1; i <= n; i++) fac[i] = 1ll * fac[i - 1] * i % mod;
    ifac[n] = qpow(fac[n]);
    for (int i = n; i >= 1; i--) ifac[i - 1] = 1ll * ifac[i] * i % mod;
}
inline int C(int n, int m) {
    return 1ll * fac[n] * ifac[n - m] % mod * ifac[m] % mod;
}

vector<int> adj[N];
int pw[N], n, m;

int dep[N], vis[N], cir;
int dp[N][2], sz[N], ans;
void dfs1(int u, int fa) {
    sz[u] = 1;
    vis[u] = 1;
    dep[u] = dep[fa] + 1;
    dp[u][0] = 2;
    for (auto v: adj[u]) {
        if (v == fa) continue;
        if (vis[v]) {
            if (dep[v] < dep[u]) continue;
            cir = dep[v] - dep[u] + 1;
            dp[u][0] = (1ll * dp[u][0] * (pw[sz[v] - 1] + dp[v][0])) % mod;
            continue;
        }
        dfs1(v, u);
        sz[u] += sz[v];
        dp[u][0] = 1ll * dp[u][0] * (pw[sz[v] - 1] + dp[v][0]) % mod;
    }
    // printf("dp[%d] = %d, val = %d\n", u, dp[u][0], 1ll * dp[u][0] * pw[max(0, m - sz[u])] % mod);
    ans = (ans + 1ll * dp[u][0] * pw[max(0, m - sz[u])]) % mod;
    // if (u == 4 || u == 2 || u == 3)
    //     ans = (ans + 1ll * dp[u][0] * pw[max(0, m - sz[u])]) % mod;
}

namespace BRUTE {
int U[222], V[222];
bool E[222][17][17];
void floyd(bool E[17][17]) {
    for (int k = 1; k <= n; k++)
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                E[i][j] |= E[i][k] & E[k][j];
}
void MAIN() {
    for (int i = 1; i <= m; i++) {
        U[i] = IO::read(), V[i] = IO::read();
    }
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) E[i][j][j] = 1;
        for (int j = 1; j <= m; j++) {
            if (i != j) {
                E[i][U[j]][V[j]] = E[i][V[j]][U[j]] = 1;
            }
        }
        floyd(E[i]);
    }
    int ans = 0;
    for (int S = 1; S < 1 << n; S++) {
        vector<int> dot;
        for (int i = 1; i <= n; i++)
            if (S >> (i - 1) & 1)
                dot.push_back(i);
        int res = 1;
        for (int i = 1; i <= m; i++) {
            bool ok = 1;
            for (auto u: dot)
                for (auto v: dot)
                    if (!E[i][u][v]) {
                        ok = 0;
                        break;
                    }
            if (ok) res = 2 * res % mod;
        }
        ans = (ans + res) % mod;
    }
    printf("%d\n", ans);
}
}

int main() {
    freopen("barrack.in", "r", stdin);
    freopen("barrack.out", "w", stdout);
    n = IO::read(), m = IO::read();
    if (m <= 25) {
        BRUTE::MAIN();
        return 0;
    }
    init(max(n, m));
    pw[0] = 1;
    for (int i = 1; i <= max(n, m); i++) pw[i] = 2 * pw[i - 1] % mod;
    for (int i = 1; i <= m; i++) {
        int u = IO::read(), v = IO::read();
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs1(1, 0);
    if (m == n - 1) {
        for (int i = 0; i <= m; i++)
            ans = (ans - 1ll * C(m, i) * (i + 1)) % mod;
    } else {
        for (int i = 0; i <= m; i++)
            ans = (ans - 1ll * C(m, i) * (i + 1)) % mod;
        ans = (ans + pw[m - cir]) % mod;
    }
    ans = (ans + mod) % mod;
    printf("%d\n", ans);
    return 0;
}

/*
10 9
1 2
1 3
2 4
3 5
3 6
3 7
7 8
8 9
7 10
*/