#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 7;
long long mypower(long long a, long long b) {
  long long res = 1;
  while (b) {
    if (b & 1) {
      res = res * a % MOD;
    }
    b >>= 1;
    a = a * a % MOD;
  }
  return res;
}
const int N = 5e5 + 10;
vector<int> graph[N];
int mark[N];
int visit[N];
int inStack[N];
int dfn[N];
int low[N];
int pa[N];
long long num[N];
long long inv2[N];
long long eVertex;
long long eEdge;
long long eCycle;
long long eVertexPair;
long long eEdgePair;
long long eCyclePair;
long long eVertexEdge;
long long eVertexCycle;
long long eEdgeCyle;
vector<int> cycle[N];
long long cycleTotalSum;
long long cycleSum[N];
long long edgeCnt[N];
void tarjan(int u, int pre, int &idx, int &comIdx) {
  dfn[u] = low[u] = ++idx;
  visit[u] = 1;
  for (auto v : graph[u]) {
    if (!visit[v]) {
      tarjan(v, u, idx, comIdx);
      low[u] = min(low[u], low[v]);
      if (low[v] < dfn[u]) {
        num[u] = num[v] + 1;
        mark[u] = mark[v];
        cycle[mark[u]].push_back(u);
      } else if (low[v] == dfn[u]) {
        int cnt = num[v];
        cycleTotalSum = (cycleTotalSum + inv2[cnt]) % MOD;
        cycleSum[u] = (cycleSum[u] + inv2[cnt]) % MOD;
        cycle[mark[v]].push_back(u);
      }
    } else if (v != pre) {
      low[u] = min(low[u], dfn[v]);
      if (low[u] == dfn[v]) {
        num[u] = 2;
        mark[u] = ++comIdx;
        cycle[comIdx].push_back(u);
      }
    }
  }
}
int main() {
  int n, m, u, v;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &u, &v);
    graph[u].push_back(v);
    graph[v].push_back(u);
  }
  inv2[0] = 1;
  inv2[1] = mypower(2, MOD - 2);
  for (int i = 1; i < N; i++) {
    inv2[i] = inv2[i - 1] * inv2[1] % MOD;
  }
  if (n == 1) {
    printf("%lld\n", inv2[2]);
    return 0;
  }
  int idx = 0;
  int comIdx = 0;
  tarjan(1, 0, idx, comIdx);
  for (int i = 1; i <= n; i++) {
    for (auto u : graph[i]) {
      if (u < i) {
        continue;
      }
      int c1 = graph[i].size();
      int c2 = graph[u].size();
      eEdgePair = (eEdgePair + (c1 - 1 + c2 - 1) * inv2[3] +
                   (m + 1 - c1 - c2 + MOD) * inv2[4]) %
                  MOD;
    }
    if (mark[i]) {
      int com = mark[i];
      cycleSum[i] = (cycleSum[i] + inv2[cycle[com].size()]) % MOD;
    }
  }
  for (int i = 1; i <= comIdx; i++) {
    long long sum = 0;
    long long edgeCnt = 0;
    for (auto u : cycle[i]) {
      sum = (sum + cycleSum[u] - inv2[cycle[i].size()] + MOD) % MOD;
      edgeCnt += graph[u].size();
    }
    int cnt = cycle[i].size();
    eCyclePair =
        (eCyclePair + sum * inv2[cnt - 1] +
         inv2[cnt] * (cycleTotalSum - sum - inv2[cnt] + 2 * MOD) % MOD) %
        MOD;
    eCycle = (eCycle + inv2[cnt]) % MOD;
    eVertexCycle =
        (eVertexCycle + cnt * inv2[cnt] + (n - cnt) * inv2[cnt + 1]) % MOD;
    edgeCnt -= 2 * cnt;
    eEdgeCyle = (eEdgeCyle + (cnt * inv2[cnt] + edgeCnt * inv2[cnt + 1] +
                              (m - cnt - edgeCnt) * inv2[cnt + 2])) %
                MOD;
  }
  eVertex = n * inv2[1] % MOD;
  eEdge = m * inv2[2] % MOD;
  eVertexPair = (eVertex + ((long long)n * (n - 1)) % MOD * inv2[2]) % MOD;
  eCyclePair = (eCyclePair + eCycle) % MOD;
  eEdgePair = (eEdgePair + eEdge) % MOD;
  eVertexEdge = m * ((2 * inv2[2] + (n - 2) * inv2[3]) % MOD) % MOD;
  long long ex = (eVertex - eEdge + eCycle + MOD) % MOD;
  long long sqrEx = ex * ex % MOD;
  long long eSqrX = ((eVertexPair + eEdgePair + eCyclePair) % MOD -
                     2 * (eVertexEdge - eVertexCycle + eEdgeCyle) % MOD + MOD) %
                    MOD;
  long long ans = (eSqrX - sqrEx + MOD) % MOD;
  printf("%lld\n", ans);
  return 0;
}
