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

#define Reimu inline void
#define Marisa inline int
#define Sanae inline bool
#define Reisen inline LL

typedef long long LL;
typedef unsigned long long ULL;

typedef pair<int, int> Pii;
typedef tuple<int, int, int> Tiii;
#define fi first
#define se second

struct ModInt {
	static const int P = 1e9 + 7;
	static Marisa reduce(int x) { return x < P ? x : x - P; }

	int x;
	ModInt(int x = 0): x(x) {}

	friend ModInt operator-(ModInt a) { return reduce(P - a.x); }
	friend ModInt operator+(ModInt a, ModInt b) { return reduce(a.x + b.x); }
	friend ModInt operator-(ModInt a, ModInt b) { return reduce(P + a.x - b.x); }
	friend ModInt operator*(ModInt a, ModInt b) { return int(1LL * a.x * b.x % P); }

	friend ModInt &operator+=(ModInt &a, ModInt b) { return a = a + b; }
	friend ModInt &operator-=(ModInt &a, ModInt b) { return a = a - b; }
	friend ModInt &operator*=(ModInt &a, ModInt b) { return a = a * b; }

	friend ModInt qpow(ModInt a, int b = P - 2) { ModInt res = 1; for (; b; b >>= 1, a *= a) if (b & 1) res *= a; return res; }

	friend ModInt operator/(ModInt a, ModInt b) { return a * qpow(b); }
	friend ModInt &operator/=(ModInt &a, ModInt b) { return a *= qpow(b); }
	
	friend istream &operator>>(istream &cin, ModInt &a) { return cin >> a.x; }
	friend ostream &operator<<(ostream &cout, ModInt a) { return cout << a.x; }
};

const int N = 500010, M = 1000010;

int n, m, top, tot, scc;
int bel[N], cnt[N], dfn[N], low[N], Stk[N], sz[N];
ModInt ans;
ModInt pw2[M], dp[N];
vector<int> G[N], tr[N];

Reimu Tar(int x, int fa) {
	low[x] = dfn[x] = ++tot;
	Stk[++top] = x;
	for (int y: G[x]) if (y ^ fa) {
		if (dfn[y]) low[x] = min(low[x], dfn[y]);
		else Tar(y, x), low[x] = min(low[x], low[y]);
	}
	if (low[x] ^ dfn[x]) return; 
	++scc; do ++cnt[bel[Stk[top]] = scc]; while(Stk[top--] ^ x);
}
Reimu dfs(int x, int fa) {
	sz[x] = 1; dp[x] = pw2[cnt[x]] - 1;
	ModInt F = 1;
	for (int y: tr[x]) if (y ^ fa) {
		dfs(y, x);
		sz[x] += sz[y];
		dp[x] = (dp[x] + F) * dp[y] + dp[x] * pw2[sz[y]];
		F *= pw2[sz[y]];
	}
	ans += dp[x] * pw2[max(scc - sz[x] - 1, 0)];
}

signed main() {
	freopen("barrack.in", "r", stdin);
	freopen("barrack.out", "w", stdout);
	ios::sync_with_stdio(false); cin.tie(nullptr);
	cin >> n >> m;
	pw2[0] = 1;
	for (int i = 1; i <= m; ++i) pw2[i] = pw2[i - 1] + pw2[i - 1];
	for (int i = 1, x, y; i <= m; ++i) cin >> x >> y, G[x].emplace_back(y), G[y].emplace_back(x);
	Tar(1, 0);
	for (int i = 1; i <= n; ++i) for (int j: G[i]) if (bel[i] ^ bel[j]) tr[bel[i]].emplace_back(bel[j]);
	dfs(1, 0);
	cout << ans * pw2[m - scc + 1] << '\n';
	return 0;
}

