#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PP;
#define MOD 1000000007
//#define MOD 998244353
#define INF 1145141919810893364
//#define INF 810114514
#define PI 3.141592653589
#define setdouble setprecision
#define REP(i,n) for(int i=0;i<(n);++i)
#define OREP(i,n) for(int i=1;i<=(n);++i)
#define RREP(i,n) for(int i=(n)-1;i>=0;--i)
#define GOODBYE do { cout << "0" << endl; return 0; } while (false)
#define MM <<" "<<
#define Endl endl
#define debug false
#define debug2 false

long long power(long long b,long long e){
  long long r=1;
  while(e){
      if(e&1){
          r=(r*b)%MOD;
      }
      b=(b*b)%MOD;
      e >>=1;
  }
  return r;
}


int main(void){
    ll N,M;
    cin >> N >> M;
    vector<ll> dp,dp2;
    vector<ll> pow2;
    pow2.push_back(1);
    REP(i,M){
        pow2.push_back((pow2[pow2.size()-1]*2)%MOD);
    }
    
    dp=pow2;
    dp2.resize(M+1,0);
    ll inv2 = power(2,MOD-2);
    
    
    //dp2[n][m]:=dp[n][m]*m*2^{-m}
    
    for(ll n=2;n<=N;n++){
        vector<ll> temp(M+1,0);
        
        //dp2[n][m]=dp[n][m]*m*2^{-m}
        ll invpow = inv2;
        for(ll m=1;m<=M;m++){
            dp2[m] = (((dp[m]*m)%MOD)*invpow)%MOD;
            invpow = (invpow*inv2)%MOD;
        }
        
        //tempはdp2の累積和
        for(ll m=1;m<=M;m++){
            if(m==1){
                temp[m]=dp2[m];
                temp[m]%=MOD;
            }else{
                temp[m]=temp[m-1]+dp2[m];
                temp[m]%=MOD;
            }
        }
        
        //そのtempに2^mをかける
        int pospow = 2;
        for(ll m=1;m<=M;m++){
            temp[m] = (temp[m]*pospow)%MOD;
            pospow = (pospow*2)%MOD;
        }
        
        //dpにm+1をかける
        for(ll m=1;m<=M;m++){
            dp[m] = (dp[m]*(m+1))%MOD;
        }
        
        //dp[m]とtemp[m-1]を足して完了
        for(ll m=2;m<=M;m++){
            dp[m] += temp[m-1];
            dp[m]%=MOD;
        }
        
        /*
        for(ll m=1;m<=M;m++){
            cout << dp[m] << " ";
        }cout << endl;
        */
    }
    
    cout << dp[M] << endl;
    
    
    return 0;
}

