#include<bits/stdc++.h>
using namespace std;
const int maxn = 500050, maxm = 2000010, mod = 1e9 + 7;
#define ll long long
int n, m;
int head[maxn + 100], ver[maxm], Next[maxm], tot = 1;
int hc[maxn], vc[maxm], nc[maxm], tc;
ll qpow[maxm + 100], dp[maxn]; 
int dfn[maxn], low[maxn], cut[maxm], dcc[maxn], edge_num[maxn], point_num[maxn], cnt, tim, vis[maxn];
int siz_edge[maxn];
int num = 0;
inline int read() {
	int x = 0, f = 1; char c = getchar();
	while (!isdigit(c)) {
		if (c == '-') f = -1;
		c = getchar();
	}
	while (isdigit(c)) {
		x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();
	}
	return x * f;
}
void add(int x, int y) {
	ver[++tot] = y, Next[tot] = head[x], head[x] = tot;
}

void add_c(int x, int y) {
	vc[++tc] = y, nc[tc] = hc[x], hc[x] = tc;
}
void tarjan(int x, int in_edge) {
	dfn[x] = low[x] = ++tim;
	for (int i = head[x]; i; i = Next[i]) {
		if (i == (in_edge ^ 1)) continue;
		int y = ver[i];
		if (!dfn[y]) {
			tarjan(y, i); low[x] = min(low[x], low[y]);
			if (low[y] > dfn[x]) cut[i] = cut[i^1] = 1;
		}else {
			low[x] = min(low[x], dfn[y]);
		}
	}
}
void dfs(int x) {
	dcc[x] = cnt;
	for (int i = head[x]; i; i = Next[i]) {
		int y = ver[i];
		if (dcc[y] || cut[i]) continue;
		dfs(y);
	}
}
void dp_work(int x) {
	//cout << x << " x" << endl;
	siz_edge[x] = edge_num[x]; dp[x] = 0; vis[x] = 1;
	int fa_edge = 0;
	for (int i = hc[x]; i; i = nc[i]) {
		int y = vc[i];
		if (vis[y]) {
			fa_edge = i; continue;
		}
		dp_work(y); //siz_edge[x] += 1 + siz_edge[y];
	}
	dp[x] =  (qpow[point_num[x]]-1) % mod * qpow[edge_num[x]] % mod; //dp[x] = dp[x] - qpow[siz_edge[x]];
	//dp[x] = (dp[x] + mod) % mod;
	for (int i = hc[x]; i; i = Next[i]) {
		int y = vc[i];
		if (i == fa_edge) continue;
	//	cout << x << " " << dp[x] << endl;
		dp[x] = dp[x] * qpow[siz_edge[y]+1] % mod + dp[x] * dp[y] % mod;
		siz_edge[x] += 1 + siz_edge[y];
		dp[x] = (dp[x] + dp[y] * qpow[siz_edge[x]-siz_edge[y]] % mod) % mod;
	}
	/*
	ll res = 1;
	for (int i = hc[x]; i; i = nc[i]) {
		int y = vc[i];
		if (i == fa_edge) continue;
		dp[x] = (dp[x] + qpow[siz_edge[x]-siz_edge[y]-1] * dp[y] % mod) % mod;
	//	cout << y << " debug " << qpow[siz_edge[x]-siz_edge[y]-1] * dp[y] % mod << endl;
		res = res * ((dp[y] + qpow[siz_edge[y]+1]) % mod) % mod;
	}
	cout << dp[x] << " dp" << " " << res << " " << qpow[point_num[x]] % mod * qpow[edge_num[x]] % mod << endl;
	res = res * qpow[point_num[x]] % mod * qpow[edge_num[x]] % mod;
	dp[x] = (dp[x] + res) % mod;
	dp[x] = dp[x] - qpow[siz_edge[x]];
	dp[x] = (dp[x] + mod) % mod;
	cout << x << " " << dp[x] << " dp" << endl;
	*/
}
int main() {
	freopen("barrack.in", "r", stdin);
	freopen("barrack.out", "w", stdout);
	n = read(); m = read();
	for (int i = 1; i <= m; i++) {
		int x = read(), y = read();  
		add(x, y); add(y, x);
	}
	qpow[0] = 1;
	for (int i = 1; i <= m + 100; i++) qpow[i] = qpow[i-1] * 2ll % mod;
	for (int i = 1; i <= n; i++) {
		if (!dfn[i]) tarjan(i, 0);
	}
	for (int i = 1; i <= n; i++) {
		if (!dcc[i]) {cnt++; dfs(i);}
	}
	for (int i = 1; i <= n; i++) {
		point_num[dcc[i]]++;
	//	cout << dcc[i] << " ";
	}
	for (int i = 2; i <= tot; i += 2) {
		int x = ver[i], y = ver[i ^ 1];
	//	cout << x << " " << y << endl;
		if (dcc[x] == dcc[y]) edge_num[dcc[x]]++;
		else {
		//	cout << dcc[x] << " " << dcc[y] << " edge" << endl;
			add_c(dcc[x], dcc[y]); add_c(dcc[y], dcc[x]);
		}
	}
	if (cnt == 1) {
		ll ans = (qpow[point_num[1]]-1) % mod * qpow[edge_num[1]] % mod; return 0;
	}
	dp_work(1);
	ll ans = dp[1];
	ans = (ans % mod + mod) % mod;
	printf("%lld\n", ans);
	return 0;
}
