#include <bits/stdc++.h>
using namespace std;

template<typename T>
ostream& operator<<(ostream& ost, const vector<T>& a) {
	bool first = true;
	for (const T& x : a) {
		if (!first) ost << ",";
		ost << x, first = false;
	}
	return ost;
}

void debug_out() { cerr << "\n"; }

template<typename U, typename... T>
void debug_out(const U& x, const T&... args) {
	cerr << " " << x;
	debug_out(args...);
}

#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__) // debuger

constexpr int mod = 1000000007;

void sub(int& x) {
	if (x >= mod) x -= mod;
}

template<typename T = int>
int power(int a, T x = mod - 2) {
	int res = 1;
	while (x) {
		if (x & 1) res = (long long) res * a % mod;
		x >>= 1;
		a = (long long) a * a % mod;
	}
	return res;
}

int main() {
	freopen("barrack.in", "r", stdin);
	freopen("barrack.out", "w", stdout);
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n, m;
	cin >> n >> m;
	vector<vector<int>> G(n);
	for (int i = 0; i < m; ++i) {
		int u, v;
		cin >> u >> v, --u, --v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	int te_cur = 0;
	vector<int> te(n, -1);
	{
		int dfs_cur = 0;
		vector<int> dfn(n, -1), low(n, -1);
		vector<int> fa(n, -1);
		int nq = 0;
		vector<int> q(n);
		auto make_te = [&](int root) {
			int tid = te_cur++;
			while (true) {
				int x = q[--nq];
				te[x] = tid;
				if (x == root) break;
			}
		};
		auto dfs = [&](auto dfs, int u)->void {
			low[u] = dfn[u] = dfs_cur++;
			q[nq++] = u;
			for (const int& v : G[u]) if (v != fa[u]) {
				if (!~dfn[v]) {
					fa[v] = u;
					dfs(dfs, v);
					if (low[v] > dfn[u]) make_te(v);
					else low[u] = min(low[u], low[v]);
				}
				else low[u] = min(low[u], dfn[v]);
			}
		};
		dfs(dfs, 0);
		make_te(0);
	}
	vector<vector<int>> T(te_cur);
	vector<int> cnt(te_cur);
	int edge = 0;
	for (int u = 0; u < n; ++u) {
		cnt[te[u]] += 1;
		for (const int& v : G[u]) if (te[u] != te[v]) {
			T[te[u]].push_back(te[v]);
			edge += 1;
		}
	}
	const int i2 = power(2);
	vector<int> pw(max(n, m) + 1, 1);
	for (size_t i = 1; i < pw.size(); ++i) pw[i] = (long long) pw[i - 1] * 2 % mod;
	vector<int> f(te_cur), g(te_cur);
	auto dfs = [&](auto dfs, int u, int fa)->void {
		f[u] = pw[cnt[u]] - 1;
		g[u] = 1;
		for (const int& v : T[u]) if (v != fa) {
			dfs(dfs, v, u);
			f[u] = (long long) f[u] * (1 + (long long) (f[v] + g[v]) * i2 % mod) % mod;
			g[u] = (long long) g[u] * (1 + (long long) (f[v] + g[v]) * i2 % mod) % mod;
		} 
		sub(g[u] += mod - 1);
	};
	dfs(dfs, 0, -1);
	int res = accumulate(f.begin(), f.end(), 0ll) % mod * pw[m] % mod;
	cout << res << '\n';
}