#include <bits/stdc++.h>
using namespace std;
using PII = pair<int, int>;
using ll = long long;
set<PII> edges, edges2;
const int N = 5e5 + 10, M = 2e6 + 20, P = 1e9 + 7;
int h[N], e[M], ne[M], idx;
int dfn[N], low[N], cnt;
int stk[N], top, scc[N], scccnt, siz[N], siz2[N];
int n, m;

int H[N], E[M], NE[M], IDX;

void ADD(int u, int v)
{
    E[IDX] = v, NE[IDX] = H[u], H[u] = IDX++;
    E[IDX] = u, NE[IDX] = H[v], H[v] = IDX++;
}

void add(int u, int v)
{
    e[idx] = v, ne[idx] = h[u], h[u] = idx++;
    e[idx] = u, ne[idx] = h[v], h[v] = idx++;
}

void tarjan(int u, int in_edge)
{
    dfn[u] = low[u] = ++cnt;
    stk[++top] = u;
    for (int i = h[u]; ~i; i = ne[i])
    {
        int &v = e[i];
        if (!dfn[v])
        {
            tarjan(v, i);
            low[u] = min(low[u], low[v]);
        }
        else if (i != (in_edge ^ 1))
        {
            low[u] = min(low[u], dfn[v]);
        }
    }
    if (dfn[u] == low[u])
    {
        // scc[u] = ++scccnt;
        ++scccnt;
        int dt = 0;
        do
        {
            scc[stk[top]] = scccnt;
            dt++;
        } while (stk[top--] != u);
        siz[scccnt] = dt;
    }
}

ll qpow(int a, int x)
{
    ll res = 1;
    while (x)
    {
        if (x & 1)
            res = res * a % P;
        a = (ll)a * a % P;
        x >>= 1;
    }
    return res;
}
ll ans = 0;

PII dfs(int u, int fa)
{
    PII trsz = {siz[u], siz2[u]};
    for (int i = H[u]; ~i; i = NE[i])
    {
        int &v = E[i];
        if (v == fa)
            continue;
        PII d = dfs(v, u);
        trsz.first += d.first;
        trsz.second += d.second + 1;
    }
    if (fa != -1)
    {
        // printf("trsz = %d\n", trsz);
        ll l = (qpow(2, trsz.first) - 1) * (qpow(2, trsz.second));
        ll r = (qpow(2, n - trsz.first) - 1) * (qpow(2, m - trsz.second - 1));
        // printf("l = %lld, r= %lld\n", l, r);
        ans -= l * r;
        ans %= P;
    }
    return trsz;
}

int main(void)
{
    freopen("barrack.in", "r", stdin);
    freopen("barrack.out", "w", stdout);
    memset(h, -1, sizeof h);
    memset(H, -1, sizeof H);
    scanf("%d%d", &n, &m);
    int flg = 1;
    for (int i = 1; i <= m; i++)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        add(u, v);
        if(!(u - 1 == v || v - 1 == u)) flg = 0;
    }
    if(m == n - 1 && flg)
    {
        ll ans = qpow(2, m) * m;
        ans += ((ll)n * (n - 1) / 2) % P * qpow(2, n - 1);
        printf("%lld\n", ans);
        return 0;
    }

    tarjan(1, -1);

    // for(int i = 1; i <= n; i++) printf("%d: %d\n", i, scc[i]);

    // return 0;
    for (int u = 1; u <= n; u++)
        for (int i = h[u]; ~i; i = ne[i])
        {
            int &v = e[i];
            if (scc[u] == scc[v])
            {
                if(!(edges2.count(make_pair(u, v)) || edges2.count(make_pair(v, u))))
                    siz2[scc[u]]++, edges2.insert(make_pair(u, v));
                continue;
            }
            if (edges.count(make_pair(scc[u], scc[v])) || edges.count(make_pair(scc[v], scc[u])))
                continue;
            edges.insert(make_pair(scc[u], scc[v]));
            ADD(scc[u], scc[v]);
        }

    ans = qpow(2, n + m) - qpow(2, m);
    // printf("%lld\n", ans);
    dfs(1, -1);
    ans = (ans % P + P) % P;
    printf("%lld\n", ans);
}