// 缩点之后树形dp，乘上2^无用的联通分量内部的边，减去2^m
# include <bits/stdc++.h>
# define int long long
# define wheneveright bool mem2; signed main
using namespace std;

bool mem1;

const int maxn = 500005;
const int maxe = 2000006;
const int mod = 1000000007;

int KSM (int x, int y = mod - 2) {
	int ret = 1;
	while (y) {
		if (y & 1) ret = ret * x % mod;
		x = x * x % mod; y >>= 1;
	}
	return ret % mod;
}

struct reader {
	template <typename Type>
	reader & operator >> (Type & ret) {
		int f = 1; ret = 0; char ch = getchar ();
		for (;!isdigit (ch); ch = getchar ()) if (ch == '-') f = -f;
		for (; isdigit (ch); ch = getchar ()) ret = ret * 10 + ch - '0';
		ret *= f; return * this;
	}
} fin;

int n, m, x, y, res;
struct Graph {
	int lnk[maxn], nxt[maxe], son[maxe], tot;
	void add_e (int x, int y) {
		nxt[++tot] = lnk[x]; lnk[x] = tot; son[tot] = y;
	}
} A, B;

int dfn[maxn], low[maxn], dft;
int bel[maxn], stk[maxn], top, scc;
bool ins[maxn]; int siz[maxn];

void Tarjan (int id, int fa) {
	dfn[id] = low[id] = ++dft; ins[id] = true; stk[++top] = id;
	for (int j = A.lnk[id]; j; j = A.nxt[j])
		if (A.son[j] != fa) {
			if (!dfn[A.son[j]]) Tarjan (A.son[j], id), low[id] = min (low[id], low[A.son[j]]);
			else if (ins[A.son[j]]) low[id] = min (low[id], dfn[A.son[j]]);
		}
	if (dfn[id] == low[id]) {
		siz[++scc] = 0;
		do {
			siz[bel[stk[top]] = scc]++;
			ins[stk[top]] = false;
		} 
		while (stk[top--] != id);
	}
	return ;
}

int f[maxn][3];

void dfs (int id, int fa) {
	f[id][0] = 1; f[id][2] = KSM (2, siz[id]); f[id][1] = 0;
	for (int j = B.lnk[id], v; j; j = B.nxt[j]) {
		if ((v = B.son[j]) == fa) continue ; dfs (v, id);
		f[id][0] = f[id][0] * f[v][0] % mod * 2 % mod;
		f[id][2] = f[id][2] * ((f[v][0] * 2 + f[v][2]) % mod) % mod;
	}
	f[id][2] = (f[id][2] - f[id][0]) % mod;
	for (int j = B.lnk[id], v; j; j = B.nxt[j]) {
		if ((v = B.son[j]) == fa) continue ;
		f[id][1] = (f[id][1] + (f[v][1] * 2 + f[v][2]) % mod * f[id][0] % mod * KSM (f[v][0] * 2 % mod)) % mod;
	}
	return ;
}

wheneveright () {
	cerr << "Memory Cost : " << abs (& mem1 - & mem2) / 1024. / 1024. << " MB\n";
	freopen ("barrack.in", "r", stdin);
	freopen ("barrack.out", "w", stdout);
	fin >> n >> m;
	while (m--) fin >> x >> y, A.add_e (x, y), A.add_e (y, x); m = 0;
	for (int i = 1; i <= n; i++) if (!dfn[i]) Tarjan (i, i);
	for (int i = 1; i <= n; i++)
		for (int j = A.lnk[i]; j; j = A.nxt[j])
			if (bel[i] != bel[A.son[j]]) B.add_e (bel[i], bel[A.son[j]]);
			else m++; m /= 2;
	dfs (1, 1);
	printf ("%lld\n", (((f[1][1] + f[1][2]) % mod * KSM (2, m) % mod) % mod + mod) % mod);
	return 0;
}