#include <bits/stdc++.h>
using namespace std;
template <class T>
T read() {
  T x = 0, w = 1;
  char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-') w = -w;
  for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
  return x * w;
}
template <class T>
inline T read(T& x) {
  return x = read<T>();
}
const int mod = 1e9 + 7;
inline int add(int a, int b) { return (a += b) >= mod ? a - mod : a; }
inline int sub(int a, int b) { return (a -= b) < 0 ? a + mod : a; }
inline int mul(int a, int b) { return (long long)a * b % mod; }
const int N = 5e5 + 10;
int n, m, pw[N];
vector<int> to[N];
int vis[N], stk[N], pos[N], idx;
vector<vector<int> > cyc;
vector<int> in[N];
void dfs(int u, int fa) {
  vis[u] = 1, stk[++idx] = u, pos[u] = idx;
  for (int v : to[u])
    if (v != fa and vis[v] != 2) {
      if (!vis[v])
        dfs(v, u);
      else
        cyc.emplace_back(stk + pos[v], stk + idx + 1);
    }
  vis[u] = 2, --idx;
}
int ver() {
  int ans = mul(n, pw[1]);
  ans = add(ans, mul(n, mul(n - 1, pw[2])));
  return ans;
}
int edge() {
  int ans = mul(m, pw[2]);
  for (int u = 1; u <= n; ++u)
    for (int v : to[u])
      if (u < v) {
        int s1 = m - to[u].size() - to[v].size() + 1;
        int s2 = to[u].size() + to[v].size() - 2;
        ans = add(ans, mul(s1, pw[4]));
        ans = add(ans, mul(s2, pw[3]));
      }
  return ans;
}
int cycle() {
  int sum = 0;
  for (const vector<int>& cir : cyc) sum = add(sum, pw[cir.size()]);
  int ans = 0;
  for (const vector<int>& cir : cyc) {
    int siz = cir.size(), val = sum;
    ans = add(ans, pw[siz]);
    for (int u : cir) {
      for (int c : in[u]) val = sub(val, pw[c]);
      val = add(val, pw[siz]);
    }
    val = sub(val, pw[siz]);
    ans = add(ans, mul(pw[siz], val));
    int ano = sub(sum, add(val, pw[siz]));
    ans = add(ans, mul(ano, mul(2, pw[siz])));
  }
  return ans;
}
int veredge() {
  int ans = 0;
  for (int u = 1; u <= n; ++u) {
    int s1 = to[u].size();
    int s2 = m - to[u].size();
    ans = add(ans, mul(s1, pw[2]));
    ans = add(ans, mul(s2, pw[3]));
  }
  return ans;
}
int vercycle() {
  int sum = 0;
  for (const vector<int>& cir : cyc) sum = add(sum, pw[cir.size()]);
  int ans = 0;
  for (int u = 1; u <= n; ++u) {
    int s = 0;
    for (int c : in[u]) s = add(s, pw[c]);
    ans = add(ans, s);
    ans = add(ans, mul(sub(sum, s), pw[1]));
  }
  return ans;
}
int edgecycle() {
  int ans = 0;
  for (const vector<int>& cir : cyc) {
    int siz = cir.size(), s = 0;
    ans = add(ans, mul(siz, pw[siz]));
    for (int u : cir) s += to[u].size() - 2;
    ans = add(ans, mul(s, pw[siz + 1]));
    ans = add(ans, mul(m - siz - s, pw[siz + 2]));
  }
  return ans;
}
int calc1() {
  int s1 = add(ver(), add(edge(), cycle()));
  int s2 = sub(vercycle(), add(veredge(), edgecycle()));
  return add(s1, mul(2, s2));
}
int calc2() {
  int ans = sub(mul(n, pw[1]), mul(m, pw[2]));
  for (const vector<int>& cir : cyc) ans = add(ans, pw[cir.size()]);
  return mul(ans, ans);
}
int main() {
  read(n), read(m);
  pw[0] = 1;
  for (int i = 1; i <= n; ++i) pw[i] = mul(pw[i - 1], 5e8 + 4);
  for (int i = 1; i <= m; ++i) {
    int u = read<int>(), v = read<int>();
    to[u].push_back(v), to[v].push_back(u);
  }
  dfs(1, 0);
  for (const vector<int>& cir : cyc)
    for (int u : cir) in[u].push_back(cir.size());
  printf("%d\n", sub(calc1(), calc2()));
  return 0;
}
