#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll p = 1e9 + 7;
ll n , m , kkk , cnt , head[500003] , low[500003] , dfn[500003] , id[500003] , E[500003] , V[500003] , s[500003] , dp[500003][3] , ans;
bool f[500003];
struct node {
ll u , v , nxt;
}e[2000009];
vector <ll> g[500003];
stack <ll> st;
ll qp(ll a , ll b) {
ll base = a , ans = 1;
while (b) {
if (b & 1) ans = (ans % p * base % p) % p;
base = (base % p * base % p) % p;
b >>= 1;
}
return ans;
}
void tarjan(ll u , ll fa) {
low[u] = dfn[u] = ++kkk;
st.push(u) , f[u] = 1;
for (int i = head[u] ; i != -1 ; i = e[i].nxt) {
int tmp = e[i].v;
if (tmp == fa) continue;
if (!dfn[tmp]) tarjan(tmp , u) , low[u] = min(low[u] , low[tmp]);
else if (f[tmp]) low[u] = min(low[u] , dfn[tmp]);
}
if (low[u] == dfn[u]) {
cnt++; ll k;
do {
k = st.top(); st.pop();
id[k] = cnt , V[cnt]++ , f[k] = 0;
} while (u != k);
}
}
void dfs(ll x , ll fa) {
s[x] = E[x];
for (auto i : g[x]) {
if (i == fa) continue;
dfs(i , x); s[x] += s[i] + 1;
dp[x][0] = dp[x][0] * dp[i][0] % p * 2ll % p;
dp[x][1] = dp[x][1] * ((dp[x][0] * dp[i][1] % p + dp[x][1] * (dp[i][0] * 2ll % p + dp[i][1]) % p) % p) % p;
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
memset(head , -1 , sizeof head);
cin >> n >> m;
for (int i = 1 ; i <= m ; i++) {
cin >> e[i].u >> e[i].v;
e[i].nxt = head[e[i].u] , head[e[i].u] = i;
e[i + m].v = e[i].u , e[i + m].u = e[i].v;
e[i + m].nxt = head[e[i + m].u] , head[e[i + m].u] = i + m;
}
for (int i = 1 ; i <= n ; i++) if (!dfn[i]) tarjan(1 , -1);
for (int i = 1 ; i <= n ; i++) {
for (int j = head[i] ; j != -1 ; j = e[j].nxt) {
int tmp = e[j].v;
if (id[i] != id[tmp]) g[id[i]].push_back(id[tmp]);
else E[id[i]]++;
}
}
for (int i = 1 ; i <= cnt ; i++) {
E[i] /= 2;
dp[i][0] = qp(2 , E[i]);
dp[i][1] = qp(2 , E[i] + V[i]) - dp[i][0];
}
dfs(1 , -1);
for (int i = 2 ; i <= cnt ; i++) ans = (ans + dp[i][1] * qp(2 , s[1] - s[i] - 1) % p) % p;
ans = (ans + dp[1][1]) % p;
cout << ans;
return 0;
}