#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define sd(x) scanf("%d", &(x))
#define pii pair<int, int>
#define F first
#define S second
#define all(c) ((c).begin()), ((c).end())
#define sz(x) ((int)(x).size())
#define ld long double

template<class T,class U>
ostream& operator<<(ostream& os,const pair<T,U>& p){
	os<<"("<<p.first<<", "<<p.second<<")";
	return os;
}

template<class T>
ostream& operator <<(ostream& os,const vector<T>& v){
	os<<"{";
	for(int i = 0;i < (int)v.size(); i++){
		if(i)os<<", ";
		os<<v[i];
	}
	os<<"}";
	return os;
}

#ifdef LOCAL
#define cerr cout
#else
#endif

#define TRACE

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
	cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
	const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
const int N = 5005;

const int mod = 1e9 + 7;
inline int add(int x, int y){ x += y; if(x >= mod) x -= mod; return x;}
inline int sub(int x, int y){ x -= y; if(x < 0) x += mod; return x;}
inline int mul(int x, int y){ return (x * 1ll * y) % mod;}
inline int powr(int a, ll b){
	int x = 1 % mod;
	while(b){
		if(b & 1) x = mul(x, a);
		a = mul(a, a);
		b >>= 1;
	}
	return x;
}
inline int inv(int a){ return powr(a, mod - 2);}

int p2[2*N], invp2[2*N];
int dp[N], dp2[N];

void getDp2(){
    dp2[0] = 0;
    for(int r = 1; r < N; r++){
        dp2[r] = add(dp2[r - 1], mul(r, mul(invp2[r + 1], dp[r])));
    }
}
int main(){
    p2[0] = invp2[0] = 1;
    for(int i = 1; i < N; i++) p2[i] = add(p2[i - 1], p2[i - 1]), invp2[i] = inv(p2[i]);
    for(int i = 0; i < N; i++) dp[i] = 1;
    int n, m; cin >> n >> m;
    for(int i = 1; i <= n; i++){
        getDp2();
        for(int j = 1; j <= m; j++){
            dp[j]= mul(dp[j], j + 1);
            dp[j] = add(dp[j], mul(p2[j], dp2[j - 1]));
        }
    }
    cout << dp[m] << endl;
}	