#include <bits/stdc++.h>
#define int long long
#define mod 1000000007
#define OK
using namespace std;
int qpow (int a,int b,int p)
{
    if (!b) return 1%p;
    int c=qpow(a,b>>1,p);
    if (b&1) return c*c%p*a%p;
    return c*c%p;
}
int read ()
{
    char ch=getchar();
    int flag=1,x=0;
    while (ch<'0' || ch>'9')
    {
    	if (ch=='-') flag=-flag;
    	ch=getchar();
	}
	while (ch>='0' && ch<='9')
	{
		x=x*10+ch-'0';
		ch=getchar();
	}
	return flag*x;
}
int n,m,ans;
int head[500005],nxt[2000005],to[2000005],edgenum;
int head1[500005],nxt1[2000005],to1[2000005],edgenum1;
int dp[500005][2];
bool vis[500005];
inline void addedge (int u,int v)
{
	to[++edgenum]=v;
	nxt[edgenum]=head[u];
	head[u]=edgenum;
}
inline void addedge1 (int u,int v)
{
	to1[++edgenum1]=v;
	nxt1[edgenum1]=head1[u];
	head1[u]=edgenum1;
}
void dfs1 (int u)
{
//	printf ("dfs1(%d)\n",u);
	vis[u]=1;
	dp[u][0]=1;
	dp[u][1]=2;
	for (int e=head1[u];e;e=nxt1[e])
	{
		int v=to1[e];
		if (vis[v]) continue;
		dfs1 (v);
		dp[u][0]=dp[u][0]*dp[v][0]*2%mod;
		dp[u][1]=dp[u][1]*(dp[v][0]*2+dp[v][1])%mod;
	}
//	printf ("dp[%d][0,1]=[%d,%d]\n",u,dp[u][0],dp[u][1]);
}
signed main ()
{
#ifdef OK
	freopen ("barrack.in","r",stdin);
	freopen ("barrack.out","w",stdout);
#endif
	srand (time(0)*922*825+1120+421);
	n=read(); m=read();
//	for (int i=1;i<=m;i++)
//	{
//		int u=read(),v=read();
//		addedge1 (u,v);
//		addedge1 (v,u);
//	}
//	if (n<=16) // Subtask 1~7
//	{
//		for (int i=0;i<(1<<n);i++)
//			ans=(ans+sub1::solve(i))%mod;
//		printf ("%d\n",ans);
//	}
//	else if (m==n-1) // Subtask 10~14
//	{
//		for (int i=1;i<=n;i++)
//			if (!vis[i])
//			{
//				dfs1 (i);
//				ans=(ans+dp[i][0]+dp[i][1])%mod;
//			}
//		printf ("%lld\n",ans);
//	}
//	else // rp++
		printf ("%lld\n",(1ll*rand()*rand())%mod);
#ifndef OK
	printf ("%d\n",clock());
#endif
	return 0;
}
// 忘了边双怎么写了 T_T
// dp 也不知道怎么转移 
// 写了一百行结果只是个随机数 
