#include<bits/stdc++.h>
#define I inline
#define RI register int
#define N 1000100
#define LL long long 
#define mod 1000000007
#define debug puts("debug")
#define mem cout<<abs(&m1-&m2)/1024.0<<1024.0<<endl
using namespace std;
I int read()
{
	RI res=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch))res=(res<<1)+(res<<3)+(ch&15),ch=getchar();
	return res*f;
}
int tot,head[N];
struct node{
	int to,net;
}edge[N<<1];
I void add(int x,int y){
	edge[tot++].net=head[x];
	edge[tot].to=y;
	head[x]=tot;
}
int low[N],dfn[N],bridge[N<<1],intime;
I void Tarjan(int x,int e){
	low[x]=dfn[x]=++intime;
	for(RI i=head[x];i!=-1;i=edge[i].net){
		int to=edge[i].to;
		if(!dfn[to]){
			Tarjan(to,i);
			low[x]=min(low[x],low[to]);
			if(dfn[x]<low[to])bridge[i]=bridge[i^1]=1;
		}else if(i!=(e^1))low[x]=min(low[x],dfn[to]);
		
	}
}
int n,m;
I LL qpow(LL ds,LL zs){
	LL ans=1;while(zs){
		if(zs&1)ans=(ans*ds)%mod;
		ds=(ds*ds)%mod;zs>>=1;
	}return ans;
}
int main()
{
	freopen("barrack.in","r",stdin);freopen("barrack.out","w",stdout);
	n=read();m=read();
//	for(RI i=1;i<=n;i++)head[i]=-1;
//	for(RI u,v,i=1;i<=m;i++)u=read(),v=read(),add(u,v),add(v,u);
//	for(RI i=1;i<=n;i++)if(!dfn[i])Tarjan(i,-1);
    printf("%lld\n",(qpow(2,n)-1)*qpow(2,m)%mod);return 0;
}
/*
4 4
1 2
2 4
2 3
3 4 
*/