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

inline int read() {
    char c; bool f = true;
    while (!isdigit(c = getchar())) f = c != '-';
    int x = c ^ 48;
    while (isdigit(c = getchar())) x = x * 10 + (c ^ 48);
    return f ? x : -x;
}

const int N = 500010;
const int M = 1000010;
const int p = 1000000007;

int n, m, x, y;
vector<int> g[N];
vector<int> v, gg[N];
ll ans;

inline ll qpow(ll x, ll y) {
    ll res = 1;
    while (y) {
        if (y & 1) {
            (res *= x) %= p;
        }
        (x *= x) %= p;
        y >>= 1;
    }
    return res;
}

ll pw2[M];
inline void init() {
    pw2[0] = 1;
    for (int i = 1; i < M; i++) {
        pw2[i] = pw2[i - 1] * 2 % p;
    }
}

int dfn[N], tot;
int dif[N], fa[N], dep[N];

void dfs1(int x) {
    v.push_back(x);
    dfn[x] = ++tot;
    for (auto y : g[x]) {
        if (dfn[y]) continue;
        gg[x].push_back(y);
        fa[y] = x;
        dep[y] = dep[x] + 1;
        dfs1(y);
    }
}

int difv[N];
void dfs2(int x) {
    difv[x] = dif[x];
    for (auto y : gg[x]) {
        dfs2(y);
        difv[x] += difv[y];
    }
}

int ssc, pt[N], ed[N], bel[N];

stack<int> cur;
void dfs3(int x) {
    cur.push(x);
    for (auto y : gg[x]) {
        dfs3(y);
    }
    if (!difv[fa[x]] || !difv[x]) {
        ssc++;
        // cerr << "ssc #" << ssc << ": "; 
        while (!cur.empty()) {
            bel[cur.top()] = ssc;
            // cerr << cur.top() << " ";
            pt[ssc]++;
            if (cur.top() == x) {
                cur.pop();
                break;
            }
            cur.pop();
        }
        // cerr << endl;
    }
}

ll f[N][3];
vector<int> tr[N];
int edsum[N];
// void dfs4(int x) {
//     edsum[x] = ed[x];
//     ll prod1 = 1, prod2 = 1;
//     for (auto y : tr[x]) {
//         dfs4(y);
//         edsum[x] += edsum[y];
//         (prod1 *= 2ll * f[y][0] % p) %= p;
//         (prod2 *= (2ll * f[y][0] % p + f[y][1] % p) % p) %= p;
//         // cerr << x << " -- dfs --> " << y << " prod2 *= " << (2ll * f[y][0] % p + f[y][1] % p) % p << endl;
//     }
//     // if (prod2 > prod1) prod2 -= prod1;
//     f[x][0] = pw2[ed[x]] * prod1 % p;
//     f[x][1] = (pw2[ed[x]] * (pw2[pt[x]]) % p * (prod2) % p - pw2[ed[x]] % p * prod1 % p + p) % p;
//     f[x][2] = 0;
//     for (auto y : tr[x]) {
//         (f[x][2] +=
//             pw2[edsum[x] - edsum[y]]
//             * prod1 % p
//             * qpow(2ll * f[y][0] % p, p - 2) % p
//             * ((f[y][1] % p + 2ll * f[y][2] % p) % p) % p
//         ) %= p;
//         // cerr << "? " << edsum[x] << " " << edsum[y] << " " << pw2[edsum[x] - edsum[y]] << " " << prod1 << endl;
//         // cerr << " += " << pw2[edsum[x] - edsum[y]] * prod1 % p * qpow(2ll * f[y][0] % p, p - 2) % p << " * " << (2ll * f[y][1] + 2ll * f[y][2]) % p << endl;
//     }
//     cout << "? " << x << " " << prod1 << " " << prod2 << " " << f[x][0] << " " << f[x][1] << " " << f[x][2] << endl;
// }
void dfs4(int x) {
    edsum[x] = ed[x];
    ll prod1 = 1, prod2 = 1;
    for (auto y : tr[x]) {
        dfs4(y);
        edsum[x] += edsum[y];
        (prod1 *= 2ll * f[y][0] % p) %= p;
        (prod2 *= (2ll * f[y][0] % p + f[y][1] % p) % p) %= p;
    }
    f[x][0] = pw2[ed[x]] * prod1 % p;
    f[x][1] = (pw2[ed[x]] * pw2[pt[x]] % p * ((prod2 - prod1 + p) % p) % p + pw2[ed[x]] * (pw2[pt[x]] - 1) % p * prod1) % p;
    f[x][2] = 0;
    for (auto y : tr[x]) {
        (f[x][2] +=
            pw2[edsum[x] - edsum[y]]
            * prod1 % p
            * qpow(2ll * f[y][0] % p, p - 2) % p
            * ((f[y][1] % p + 2ll * f[y][2] % p) % p) % p
        ) %= p;
        // cerr << "? " << edsum[x] << " " << edsum[y] << " " << pw2[edsum[x] - edsum[y]] << " " << prod1 << endl;
        // cerr << " += " << pw2[edsum[x] - edsum[y]] * prod1 % p * qpow(2ll * f[y][0] % p, p - 2) % p << " * " << (2ll * f[y][1] + 2ll * f[y][2]) % p << endl;
    }
    // cout << "? " << x << " " << prod1 << " " << prod2 << " " << f[x][0] << " " << f[x][1] << " " << f[x][2] << endl;
}
inline void solve(int rt) {
    // cerr << "solve: " << rt << endl;
    v.clear();
    tot = 0;
    dep[rt] = 1;
    dfs1(rt);
    for (auto x : v) {
        for (auto y : g[x]) {
            if (fa[x] == y || fa[y] == x) continue;
            int a = x, b = y;
            if (dep[a] < dep[b]) continue;
            dif[a]++;
            dif[fa[b]]--;
        }
    }
    dfs2(rt);
    for (int i = 1; i <= ssc; i++) {
        pt[i] = ed[i] = edsum[i] = 0;
        tr[i].clear();
    }
    ssc = 0;
    while (!cur.empty()) cur.pop();
    dfs3(rt);
    int edsum = 0;
    for (auto x : v) {
        for (auto y : g[x]) {
            if (x > y) continue;
            if (bel[x] == bel[y]) {
                ed[bel[x]]++;
                // cerr << x << " -> " << y << endl;
            }
            edsum++;
        }
    }
    for (auto x : v) {
        for (auto y : g[x]) {
            if (fa[x] == y || fa[y] == x) continue;
            assert(bel[x] == bel[y]);
        }
    }
    for (auto x : v) {
        for (auto y : gg[x]) {
            if (fa[y] == x && bel[x] != bel[y]) {
                tr[bel[x]].push_back(bel[y]);
                // cerr << "addedge: " << bel[x] << " -> " << bel[y] << endl;
            }
        }
    }
    dfs4(bel[rt]);
    // cout << "? " << m << " " << edsum << endl;
    (ans += (f[bel[rt]][1] + f[bel[rt]][2]) % p * pw2[m - edsum] % p) %= p;
}

int main() {
    freopen("barrak.in", "r", stdin);
    freopen("barrak.out", "w", stdout);
    init();
    n = read(); m = read();
    for (int i = 1; i <= m; i++) {
        x = read(); y = read();
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for (int i = 1; i <= n; i++) {
        if (!dfn[i]) {
            solve(i);
        }
    }
    printf("%lld\n", ans);
    return 0;
}
/*
4 4
1 2
2 3
3 1
1 4

g++ barrak.cpp -std=c++14 -Wall -Wextra -Werror -O2 -o barrak; .\barrak

7 7
2 1
3 2
4 1
5 2
6 3
5 4
5 7

3 2
1 2
1 3

*/