#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <vector>

typedef long long LL;
#define rep(i,a,b) for(int i=a,_ds##i=b;i<=_ds##i;++i)
#define per(i,a,b) for(int i=a,_ds##i=b;i>=_ds##i;--i)
template<typename T> T rd(){T r;char c,n=0;while(!isdigit(c=getchar()))n=c=='-';r=c-'0';while(isdigit(c=getchar()))r=r*10+c-'0';return n?-r:r;}
#define rdi rd<int>
#define rdl rd<LL>

const int N = 5e5 + 5, M = 1e6 + 5;
const LL P = 1e9 + 7;

int n, m, c;
std::vector<int> G[N], T[N];
struct edge { int u, v; };
std::vector<edge> E;
int Stk[N], top = 0, Now = 0;
int Dfn[N], Low[N], Belong[N], Siz[N], Ecnt[N];
int TEcnt[N];
LL pw[M], f[N][2];

void dfs_tarjan(int x, int fa) {
    Dfn[x] = Low[x] = ++Now;
    Stk[++top] = x;
    for (int y: G[x]) if (y != fa && Dfn[y]) {
        Low[x] = std::min(Low[x], Dfn[y]);
    }
    for (int y: G[x]) if (y != fa && !Dfn[y]) {
        dfs_tarjan(y, x);
        Low[x] = std::min(Low[x], Low[y]);
    }
    if (Low[x] == Dfn[x]) {
        ++c, Siz[c] = 1, Ecnt[c] = 0;
        while (Stk[top] != x) {
            Belong[Stk[top]] = c;
            ++Siz[c]; --top;
        }
        Belong[x] = c; --top;
    }
}
void init_tree() {
    top = 0; Now = 0;
    dfs_tarjan(1, 0);
    for (edge& e: E) {
        if (Belong[e.u] == Belong[e.v])
            ++Ecnt[Belong[e.u]];
        else
            T[Belong[e.u]].push_back(Belong[e.v]),
            T[Belong[e.v]].push_back(Belong[e.u]);
    }
}
void dp_tree(int x, int fa) {
    f[x][0] = pw[Ecnt[x]];
    f[x][1] = pw[Siz[x]] * pw[Ecnt[x]] % P;
    TEcnt[x] = Ecnt[x];
    for (int y: T[x]) if (y != fa) {
        dp_tree(y, x);
        (f[x][0] *= f[y][0] * 2 % P) %= P;
        (f[x][1] *= (f[y][0] * 2 + f[y][1]) % P) %= P;
        TEcnt[x] += TEcnt[y] + 1;
    }
    f[x][1] -= f[x][0];
}
LL fas_pow(LL x, LL y) {
    if (y == 0) return 1;
    if (y == 1) return x;
    if (y & 1LL) return fas_pow(x, y - 1) * x % P;
    LL hf = fas_pow(x, y >> 1LL);
    return hf * hf % P;
}

int main() {
    freopen("barrack.in", "r", stdin);
    freopen("barrack.out", "w", stdout);
    n = rdi(), m = rdi();
    rep(i, 1, m) {
        static int u, v;
        u = rdi(), v = rdi();
        G[u].push_back(v);
        G[v].push_back(u);
        E.push_back({u, v});
    }
    pw[0] = 1;
    rep(i, 1, std::max(n, m) + 1)
        pw[i] = pw[i - 1] * 2 % P;
    init_tree();
    dp_tree(1, 0);
    LL ans = f[1][1];
    rep(i, 2, n) {
        (ans += f[i][1] * pw[TEcnt[1] - TEcnt[i] - 1] % P) %= P;
    }
    printf("%lld\n", ans);
    return 0;
}
