#include <cstring>
#include <fstream>
#include <iostream>
constexpr int kMod = 1000000007;
int add(int x, int y) { return x + y >= kMod ? x + y - kMod : x + y; }
void Add(int &x, int y) {
  if ((x += y) >= kMod) x -= kMod;
}
int sub(int x, int y) { return x < y ? x - y + kMod : x - y; }
int mul(int x, int y) { return (long long)x * y % kMod; }
std::ifstream fin("barrack.in");
std::ofstream fout("barrack.out");
struct Edge {
  int to, nxt;
} e1[2000001], e2[2000001];
int n, m, E1, E2, head1[500001], head2[500001], dfn[500001], tot, low[500001];
int st[500001], top, sz[500001], sze[500001], cnt, bel[500001];
bool vis[500001], cut[1000001];
void AddEdge1(int f, int t) { e1[E1] = {t, head1[f]}, head1[f] = E1++; }
void AddEdge2(int f, int t) { e2[E2] = {t, head2[f]}, head2[f] = E2++; }
void checkmin(int &x, int y) {
  if (x > y) x = y;
}
void Tarjan(int u, int fe) {
  dfn[u] = low[u] = ++tot;
  vis[u] = true;
  for (int i = head1[u]; i != -1; i = e1[i].nxt) {
    if (i == (fe ^ 1)) continue;
    int v = e1[i].to;
    if (!dfn[v])
      Tarjan(v, i), checkmin(low[u], low[v]);
    else if (vis[v])
      checkmin(low[u], dfn[v]);
    if (low[v] > dfn[u]) cut[i >> 1] = true;
  }
}
void Dfs0(int u) {
  // std::cerr << u << ' ';
  sz[cnt]++;
  bel[u] = cnt, vis[u] = true;
  for (int i = head1[u]; i != -1; i = e1[i].nxt) {
    if (cut[i >> 1]) continue;
    int v = e1[i].to;
    if (vis[v]) continue;
    Dfs0(v);
  }
}
int FA[500001];
int Find(int x) { return x == FA[x] ? x : FA[x] = Find(FA[x]); }
int pw[2000001], f[500001][3], ans;
void Dfs(int u, int fa) {
  f[u][0] = pw[sze[u]], f[u][2] = sub(pw[sze[u] + sz[u]], pw[sze[u]]);
  for (int i = head2[u]; i != -1; i = e2[i].nxt) {
    int v = e2[i].to;
    if (v == fa) continue;
    Dfs(v, u);
    sze[u] += sze[v] + 1;
    int f0 = f[u][0], f1 = f[u][1], f2 = f[u][2];
    f[u][0] = mul(f0, 2 * f[v][0]);
    f[u][1] = add(mul(f0, f[v][1] + f[v][2]), mul(f1, 2 * f[v][0]));
    f[u][2] = add(mul(f1, f[v][1] + f[v][2]),
                  mul(f2, (2LL * f[v][0] + f[v][1] + f[v][2]) % kMod));
  }
  Add(ans, mul(f[u][2], pw[m - sze[u]]));
}
int main(int argc, char const *argv[]) {
  // std::freopen("barrack.in", "r", stdin);
  std::cin.rdbuf(fin.rdbuf()), std::cout.rdbuf(fout.rdbuf());
  std::cin.tie(nullptr);
  std::memset(head1, -1, sizeof(head1)), std::memset(head2, -1, sizeof(head2));
  std::cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int u, v;
    std::cin >> u >> v;
    AddEdge1(u, v), AddEdge1(v, u);
  }
  Tarjan(1, -1);
  std::memset(vis, 0, sizeof(vis));
  for (int i = 1; i <= n; i++)
    if (!vis[i]) cnt++, Dfs0(i);
  for (int i = 1; i <= cnt; i++) FA[i] = i;
  for (int u = 1; u <= n; u++)
    for (int i = head1[u]; i != -1; i = e1[i].nxt) {
      int v = e1[i].to;
      if (bel[u] == bel[v]) {
        sze[bel[u]]++;
      } else {
        int fu = Find(bel[u]), fv = Find(bel[v]);
        if (fu != fv) {
          AddEdge2(bel[u], bel[v]), AddEdge2(bel[v], bel[u]);
          FA[fu] = fv;
        }
      }
    }
  for (int i = 1; i <= cnt; i++) sze[i] >>= 1;
  pw[0] = 1;
  for (int i = 1; i <= n + m; i++) pw[i] = add(pw[i - 1], pw[i - 1]);
  Dfs(1, 0);
  // for (int i = 1; i <= cnt; i++)
  //   for (int j = 0; j <= 2; j++) std::cerr << f[i][j] << " \n"[j == 2];
  std::cout << ans;
  return 0;
}