#include <cstdio>
#include <ctime>
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <utility>
#define int long long
using namespace std;
const int kMaxN = 1e6 + 5, kMaxM = 1e6 + 5, kMod = 1e9 + 7;
int n, m, cnt, tot;
int u[kMaxM], v[kMaxM], pw[kMaxN];
int sz[kMaxN], dfn[kMaxN], low[kMaxN], dcc[kMaxN];
int sum[kMaxN], f[kMaxN][5], pre[kMaxN], suf[kMaxN], id[kMaxN], s[3];
vector<int> g[kMaxN], G[kMaxN];
stack<int> stk;
map<pair<int, int>, bool> mp;
int mod(int x) {
return (x % kMod + kMod) % kMod;
}
void addE(int u, int v) {
g[u].emplace_back(v);
}
void tarjan(int u, int fa) {
dfn[u] = low[u] = ++cnt;
stk.emplace(u);
for (auto v : g[u]) {
if (!dfn[v]) {
tarjan(v, u);
low[u] = min(low[u], low[v]);
} else if (v != fa) {
low[u] = min(low[u], dfn[v]);
}
}
if (low[u] == dfn[u]) {
++tot;
while (!stk.empty()) {
int nt = stk.top();
stk.pop();
++sz[tot], dcc[nt] = tot;
if (nt == u) break;
}
}
}
void dfs(int u, int fa) {
int t, tmp;
if (u == 1) t = G[u].size();
else t = G[u].size() - 1;
if (!t) {
f[u][0] = 1, f[u][1] = pw[sz[u]] - 1;
return;
}
t = 0;
f[u][0] = f[u][3] = f[u][4] = 1;
f[u][1] = f[u][2] = tmp = pw[sz[u]] - 1;
for (auto v : G[u]) {
if (v == fa) continue ;
dfs(v, u);
f[u][0] = 2ll * f[u][0] * f[v][0] % kMod;
f[u][1] = 2ll * f[u][1] * f[v][0] % kMod;
f[u][2] = 1ll * f[u][2] * (2ll * f[v][0] + f[v][1] + f[v][2] + f[v][4]) % kMod;
id[++t] = v;
}
f[u][2] = mod(f[u][2] - f[u][1]);
pre[0] = suf[t + 1] = 1;
for (int i = 1; i <= t; ++i) pre[i] = 2ll * pre[i - 1] * f[id[i]][0] % kMod;
for (int i = t; i; --i) suf[i] = 2ll * suf[i + 1] * f[id[i]][0] % kMod;
f[u][3] = 0;
for (int i = 1; i <= t; ++i) {
int v = id[i];
f[u][3] = (f[u][3] + 2ll * pre[i - 1] * suf[i + 1] % kMod *
mod(f[v][1] + f[v][2] + f[v][3]) % kMod) % kMod;
}
s[0] = 1, s[1] = s[2] = 0;
for (int i = 1; i <= t; ++i) {
int v = id[i];
s[2] = (1ll * s[2] * mod(2ll * f[v][0] % kMod + f[v][1] + f[v][2] + f[v][4])
% kMod + 1ll * s[1] * (f[v][1] + f[v][2] + f[v][4]) % kMod) % kMod;
s[1] = (2ll * s[1] * f[v][0] % kMod + 1ll * s[0] * (f[v][1] + f[v][2] + f[v][4]) % kMod) % kMod;
s[0] = 2ll * s[0] * f[v][0] % kMod;
}
f[u][3] = (f[u][3] + s[2]) % kMod;
tmp = 1;
for (int i = 1; i <= t; ++i) {
int v = id[i];
f[u][4] = 1ll * f[u][4] * (2ll * f[v][0] + f[v][1] + f[v][2] + f[v][4]) % kMod;
tmp = 2ll * tmp * f[v][0] % kMod;
}
f[u][4] = mod(f[u][4] - tmp);
}
signed main() {
#ifdef ORZXKR
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= m; ++i) {
cin >> u[i] >> v[i];
addE(u[i], v[i]), addE(v[i], u[i]);
}
for (int i = 1; i <= n; ++i)
if (!dfn[i])
tarjan(i, 0);
for (int i = 1; i <= m; ++i) {
int x = dcc[u[i]], y = dcc[v[i]];
if (x > y) swap(x, y);
if (x == y || mp[{x, y}]) continue;
mp[{x, y}] = 1;
G[x].emplace_back(y);
G[y].emplace_back(x);
}
pw[0] = 1ll;
for (int i = 1; i <= max(n, m); ++i)
pw[i] = 2ll * pw[i - 1] % kMod;
dfs(1, 0);
cerr << tot << '\n';
cout << 1ll * mod(f[1][1] + f[1][2] + f[1][3]) * pw[m - (tot - 1)] % kMod << '\n';
cerr << 1.0 * clock() / CLOCKS_PER_SEC << 's' << '\n';
return 0;
}