// This Code was made by Chinese_zjc_.
#include <bits/stdc++.h>
const int MOD = 1000000007;
struct mint
{
    unsigned v;
    mint(unsigned v_ = 0) : v(v_) {}
    mint &operator+=(const mint &X) { return (v += X.v) >= MOD ? v -= MOD : v, *this; }
    mint &operator-=(const mint &X) { return (v += MOD - X.v) >= MOD ? v -= MOD : v, *this; }
    mint &operator*=(const mint &X) { return v = 1llu * v * X.v % MOD, *this; }
    mint &operator/=(const mint &X) { return *this *= X.inv(); }
    mint pow(long long B) const
    {
        B %= MOD - 1;
        if (B < 0)
            B += MOD - 1;
        mint res = 1, A = *this;
        while (B)
        {
            if (B & 1)
                res *= A;
            A *= A;
            B >>= 1;
        }
        return res;
    }
    mint inv() const { return pow(MOD - 2); }
    friend mint operator+(const mint &A, const mint &B) { return mint(A) += B; }
    friend mint operator-(const mint &A, const mint &B) { return mint(A) -= B; }
    friend mint operator*(const mint &A, const mint &B) { return mint(A) *= B; }
    friend mint operator/(const mint &A, const mint &B) { return mint(A) /= B; }
    friend std::istream &operator>>(std::istream &A, mint &B) { return A >> B.v; }
    friend std::ostream &operator<<(std::ostream &A, const mint &B) { return A << B.v; }
    friend bool operator==(const mint &A, const mint &B) { return A.v == B.v; }
    explicit operator bool() const { return v; }
} dp[500005][3], ans, pw[500005];
int n, m, tim, dfn[500005], low[500005], cnt, num[500005], in[500005], siz[500005];
std::stack<int> sta;
std::vector<int> t[500005], to[500005];
void Tarjan(int now, int fa = 0)
{
    sta.push(now);
    dfn[now] = low[now] = ++tim;
    for (auto i : t[now])
    {
        if (!dfn[i])
        {
            Tarjan(i, now);
            low[now] = std::min(low[now], low[i]);
        }
        else if (i != fa)
            low[now] = std::min(low[now], dfn[i]);
    }
    if (low[now] == dfn[now])
    {
        ++cnt;
        while (sta.top() != now)
        {
            in[sta.top()] = cnt;
            sta.pop();
        }
        in[sta.top()] = cnt;
        sta.pop();
    }
}
void dfs(int now, int fa = 0)
{
    siz[now] = 1;
    dp[now][0] = 1;
    for (auto i : to[now])
    {
        if (i == fa)
            continue;
        dfs(i, now);
        siz[now] += siz[i];
        dp[now][2] = dp[now][2] * (2 * dp[i][0] + dp[i][1] + dp[i][2]) +
                     dp[now][1] * (dp[i][1] + dp[i][2]);
        dp[now][1] = dp[now][1] * 2 * dp[i][0] +
                     dp[now][0] * (dp[i][1] + dp[i][2]);
        dp[now][0] = dp[now][0] * 2 * dp[i][0];
    }
    dp[now][2] = dp[now][2] * pw[num[now]] +
                 dp[now][1] * (pw[num[now]] - 1) +
                 dp[now][0] * (pw[num[now]] - 1);
    // std::cout << dp[now][0] << ' ' << dp[now][1] << ' ' << dp[now][2] << std::endl;
}
signed main()
{
    freopen("barrack.in", "r", stdin) && freopen("barrack.out", "w", stdout);
    std::ios::sync_with_stdio(false);
    std::cin >> n >> m;
    pw[0] = 1;
    for (int i = 1; i <= n; ++i)
        pw[i] = pw[i - 1] * 2;
    for (int i = 1, u, v; i <= m; ++i)
    {
        std::cin >> u >> v;
        t[u].push_back(v);
        t[v].push_back(u);
    }
    Tarjan(1);
    for (int i = 1; i <= n; ++i)
        ++num[in[i]];
    for (int i = 1; i <= n; ++i)
        for (auto j : t[i])
            if (in[i] != in[j])
                to[in[i]].push_back(in[j]);
    dfs(1);
    for (int i = 1; i <= cnt; ++i)
        ans += dp[i][2] * pw[cnt - siz[i]];
    std::cout << ans * mint(2).pow(m - cnt + 1) << std::endl;
    return 0;
}