#include <bits/stdc++.h>

#define int long long

using namespace std;

const int maxn = 5e5 + 50;
const int maxm = 1e6 + 50;
const int mod  = 1e9 + 7;

inline int add (int x, int y) { return (x + y) % mod; }
inline int mul (int x, int y) { return x * y % mod; }
inline int dec (int x, int y) { return (x + mod - y) % mod; }

inline int qpow (int x, int y)
{
	int res = 1;
	while (y)
	{
		if (y & 1) res = mul (res, x);
		x = mul (x, x);
		y >>= 1;
	}
	return res;
}

int n, m;

struct Edge {
	int u, v;
} e[maxm];

vector <int> g[maxn], E[maxn];

int dfn[maxn], low[maxn], idx;
bool in_stack[maxn];
int s[maxn], top;

int bel[maxn], N[maxn], M[maxn], scc;

inline void dfs1 (int now, int fa)
{
	bel[now] = ++idx;
	
	for (auto v : E[now])
	{
		if (v == fa) continue;
//		printf ("dfs %d -> %d\n", now, v);
		if (!bel[v]) dfs1 (v, now);
//		printf ("bel[now = %d] : %d -> %d\n", now, bel[now], min (bel[now], bel[v]));
		bel[now] = min (bel[now], bel[v]);
		
	}
}

inline void Tarjan (int now)
{
	dfn[now] = low[now] = ++idx;
	s[++top] = now; in_stack[now] = 1;
	
//	printf ("now = %d\n", now);
//	for (int i = 1; i <= top; ++i) cout << s[i] << " "; cout << "\n";
	
	for (auto v : E[now])
	  if (!dfn[v]) Tarjan (v), low[now] = min (low[now], low[v]);
	  else if (in_stack[v]) low[now] = min (low[now], dfn[v]);
	
	if (dfn[now] == low[now])
	{
//		cout << "Find " << now << '\n';
		++scc;
		do
		{
			bel[s[top]] = scc;
			in_stack[s[top]] = 0;
			++N[scc];
		} while (s[top--] != now);
	}	
}

int dp[maxn][2];

inline void dfs (int now, int fa)
{
	int sum0 = 0, sum1 = 0, mul0 = 1, mul1 = 1, son = 0;
	for (auto v : g[now])
	{
		if (v == fa) continue;
		dfs (v, now); ++son;
		sum0 = add (sum0, dp[v][0]);
		sum1 = add (sum1, dp[v][1]);
		mul0 = mul (mul0, mul (dp[v][0], 2));
		mul1 = mul (mul1, dp[v][1] + 2 * dp[v][0]);
	}
	
	dp[now][0] = mul (qpow (2, M[now]), max (1ll, mul (sum0, 2ll)));
	if (son == 0) dp[now][1] = mul (dec (qpow (2, N[now]), 1), qpow (2, M[now]));
	else {
		int a = mul (qpow (2, N[now]), mul1);
		int b = mul (2, sum1);
		int c = mul (sum1, qpow (2, son - 1));
		int d = mul0;
//		printf ("a = %d b = %d c = %d d = %d\n", a, b, c, d);
		dp[now][1] = mul (qpow (2, M[now]), dec (dec (add (a, b), c), d));
	}
//	printf ("[now = %d] : %d %d\n", now, dp[now][0], dp[now][1]);
}

int fa[maxn];
inline int find (int x) { return x == fa[x] ? x : fa[x] = find (fa[x]); }

signed main ()
{
	ios::sync_with_stdio (false); cin.tie (0); cout.tie (0);
	freopen ("barrack.in", "r", stdin);
	freopen ("barrack.out", "w", stdout);
	
	cin >> n >> m;
	for (int i = 1, u, v; i <= m; ++i) 
	{
		cin >> u >> v; 
		e[i] = (Edge){u, v};
		E[u].push_back (v);
		E[v].push_back (u);
	}
	
	for (int i = 1; i <= n; ++i)
	  if (!bel[i]) dfs1 (i, 0);
	
//	printf ("FINISHED DFS\n");
	
	for (int i = 1; i <= m; ++i)
	{
		int u = bel[e[i].u], v = bel[e[i].v];
		if (u == v) ++M[u];
		if (u != v)
		{
			g[u].push_back (v);
			g[v].push_back (u);
			
//			int U = find (u), V = find (v);
//			if (U == V) return cout << "CIRCLE" << '\n', 0;
//			fa[U] = V;
		}
	}
	
	for (int i = 1; i <= n; ++i) ++N[bel[i]];
	
//	for (int i = 1; i <= n; ++i) printf ("bel[%d] = %d\n", i, bel[i]);
//	for (int i = 1; i <= n; ++i) printf ("[%d] : N = %d M = %d\n", i, N[i], M[i]);
	
	dfs (1, 0);
	
	return cout << dp[1][1] << "\n", 0;
}

