#include <bits/stdc++.h>
using namespace std;
template <class TH>
void _dbg(const char *sdbg, TH h) {
  cerr << sdbg << '=' << h << endl;
}
template <class TH, class... TA>
void _dbg(const char *sdbg, TH h, TA... a) {
  while (*sdbg != ',') cerr << *sdbg++;
  cerr << '=' << h << ',';
  _dbg(sdbg + 1, a...);
}
template <class L, class R>
ostream &operator<<(ostream &os, pair<L, R> p) {
  return os << "(" << p.first << ", " << p.second << ")";
}
template <class Iterable,
          class = typename enable_if<!is_same<string, Iterable>::value>::type>
auto operator<<(ostream &os, Iterable v) -> decltype(os << *begin(v)) {
  os << "[";
  for (auto vv : v) os << vv << ", ";
  return os << "]";
}
const int inf = 0x3f3f3f3f;
const long long infll = 0x3f3f3f3f3f3f3f3fll;
template <class T>
int sign(T x) {
  return (x > 0) - (x < 0);
}
template <class T>
T abs(const T &x) {
  return (x < T(0)) ? -x : x;
}
template <class T>
T gcd(T a, T b, T &x, T &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  T x1, y1;
  T d = gcd(b, a % b, x1, y1);
  x = y1;
  y = x1 - y1 * (a / b);
  return d;
}
template <class T>
T mod_inverse(T a, T m) {
  T x, y;
  assert(gcd(a, m, x, y) == 1);
  return (x % m + m) % m;
}
template <long long mod>
struct mod_num {
  long long x;
  explicit mod_num(long long x = 0) : x(x % mod) {}
  mod_num operator+(mod_num b) { return mod_num(x + b.x); }
  mod_num operator-(mod_num b) { return mod_num(x - b.x + mod); }
  mod_num operator*(mod_num b) { return mod_num(x * b.x); }
  mod_num operator/(mod_num b) { return mod_num(x * mod_inverse(b.x, mod)); }
  mod_num operator^(long long e) {
    mod_num ans(1);
    mod_num b = *this;
    for (; e; b = b * b % mod, e /= 2)
      if (e & 1) ans = ans * b % mod;
    return ans;
  }
  void operator+=(mod_num b) { x = (x + b.x) % mod; }
};
template <long long mod>
ostream &operator<<(ostream &os, mod_num<mod> x) {
  return os << x.x;
}
vector<int> graph[512345];
int been[512345];
vector<int> st;
vector<vector<int>> rings;
vector<pair<int, int>> edges;
mod_num<1000000007> vertex_rings_factor[512345];
void dfs(int a, int p) {
  been[a] = 1;
  st.push_back(a);
  for (int i = 0; i < graph[a].size(); i++) {
    if (graph[a][i] != p) {
      if (been[graph[a][i]] == 0)
        dfs(graph[a][i], a);
      else if (been[graph[a][i]] == 1) {
        vector<int> tmp;
        for (int j = ((int)(st).size()) - 1; st[j] != graph[a][i]; j--)
          tmp.push_back(st[j]);
        tmp.push_back(graph[a][i]);
        rings.push_back(tmp);
      }
    }
  }
  st.pop_back();
  been[a] = 2;
}
bool intersect(const vector<int> &v1, const vector<int> &v2) {
  for (int i = 0; i < ((int)(v1).size()); i++)
    if (find(v2.begin(), v2.end(), v1[i]) != v2.end()) return true;
  return false;
}
int main() {
  cin.sync_with_stdio(0);
  cin.tie(0);
  int n, m, a, b;
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    cin >> a >> b;
    edges.push_back({min(a, b), max(a, b)});
    graph[a].push_back(b);
    graph[b].push_back(a);
  }
  dfs(1, 1);
  vector<mod_num<1000000007>> pot2div(max(11, n + 1));
  pot2div[0] = mod_num<1000000007>(1);
  for (int i = 1; i <= max(10, n); i++)
    pot2div[i] = pot2div[i - 1] / mod_num<1000000007>(2);
  mod_num<1000000007> sum_rings_factors(0);
  for (int i = 0; i < ((int)(rings).size()); i++) {
    sum_rings_factors += pot2div[((int)(rings[i]).size())];
    for (int x : rings[i]) {
      vertex_rings_factor[x] += pot2div[((int)(rings[i]).size())];
    }
  }
  vector<mod_num<1000000007>> intersecting_rings_factors(((int)(rings).size()));
  for (int i = 0; i < ((int)(rings).size()); i++)
    for (int x : rings[i])
      intersecting_rings_factors[i] +=
          vertex_rings_factor[x] - pot2div[((int)(rings[i]).size())];
  mod_num<1000000007> ex = mod_num<1000000007>(n) / mod_num<1000000007>(2) -
                           mod_num<1000000007>(m) / mod_num<1000000007>(4);
  for (int i = 0; i < rings.size(); i++)
    ex += pot2div[((int)(rings[i]).size())];
  mod_num<1000000007> ex2(0);
  mod_num<1000000007> ev2 = mod_num<1000000007>(n) *
                                mod_num<1000000007>(n - 1) /
                                mod_num<1000000007>(4) +
                            mod_num<1000000007>(n) / mod_num<1000000007>(2);
  mod_num<1000000007> ee2(0);
  for (int i = 0; i < m; i++) {
    ee2 += pot2div[2];
    ee2 += mod_num<1000000007>(((int)(graph[edges[i].first]).size()) +
                               ((int)(graph[edges[i].second]).size()) - 2) *
           pot2div[3];
    ee2 +=
        mod_num<1000000007>(m - (((int)(graph[edges[i].first]).size()) +
                                 ((int)(graph[edges[i].second]).size()) - 1)) *
        pot2div[4];
  }
  mod_num<1000000007> er2(0);
  for (int i = 0; i < ((int)(rings).size()); i++) {
    er2 += pot2div[((int)(rings[i]).size())];
    er2 +=
        pot2div[((int)(rings[i]).size()) - 1] * intersecting_rings_factors[i];
    er2 += pot2div[((int)(rings[i]).size())] *
           (sum_rings_factors - intersecting_rings_factors[i] -
            pot2div[((int)(rings[i]).size())]);
  }
  mod_num<1000000007> eve;
  for (int i = 1; i <= n; i++) {
    eve += mod_num<1000000007>(((int)(graph[i]).size())) * pot2div[2];
    eve += mod_num<1000000007>(m - ((int)(graph[i]).size())) * pot2div[3];
  }
  mod_num<1000000007> eer;
  for (int j = 0; j < ((int)(rings).size()); j++) {
    int k = ((int)(rings[j]).size());
    eer += mod_num<1000000007>(((int)(rings[j]).size())) *
           pot2div[((int)(rings[j]).size())];
    for (int x : rings[j]) {
      eer += mod_num<1000000007>(((int)(graph[x]).size()) - 2) *
             pot2div[((int)(rings[j]).size()) + 1];
      k += ((int)(graph[x]).size()) - 2;
    }
    eer += mod_num<1000000007>(m - k) * pot2div[((int)(rings[j]).size()) + 2];
  }
  mod_num<1000000007> evr;
  for (int i = 1; i <= n; i++) {
    evr += vertex_rings_factor[i];
    evr += (sum_rings_factors - vertex_rings_factor[i]) * pot2div[1];
  }
  ex2 = ev2 + ee2 + er2 - mod_num<1000000007>(2) * eve -
        mod_num<1000000007>(2) * eer + mod_num<1000000007>(2) * evr;
  cout << (ex2 - ex * ex) << endl;
}
