#line 1 "c.cpp" #include #include #define rep(i,n) for (int i = 0; i < int(n); ++i) #define repp(i,n,m) for (int i = m; i < int(n); ++i) #define reb(i,n) for (int i = int(n)-1; i >= 0; --i) #define all(v) v.begin(),v.end() using namespace std; using namespace atcoder; using ll = long long; using ull = unsigned long long; using ld = long double; using P = pair; using PL = pair; using pdd = pair; using pil = pair; using pli = pair; templateistream &operator>>(istream &is,vector &v){for(auto &e:v)is>>e;return is;} templatebool range(T a,T b,T x){return (a<=x&&xbool rrange(T a,T b,T c,T d,T x,T y){return (range(a,c,x)&&range(b,d,y));} template T rev(const T& str_or_vec){T res = str_or_vec; reverse(res.begin(),res.end()); return res; } templatebool chmin(T &a,const T &b){if(a>b){a=b;return true;}return false;} templatebool chmax(T &a,const T &b){if(avoid uniq(vector &v){sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());} templatevoid print(pair a); templatevoid print(vector v); templatevoid print(vector> v); void print(){ putchar(' '); } void print(bool a){ printf("%d", a); } void print(int a){ printf("%d", a); } void print(long a){ printf("%ld", a); } void print(long long a){ printf("%lld", a); } void print(char a){ printf("%c", a); } void print(char a[]){ printf("%s", a); } void print(const char a[]){ printf("%s", a); } void print(long double a){ printf("%.15Lf", a); } void print(const string& a){ for(auto&& i : a) print(i); } void print(unsigned int a){ printf("%u", a); } void print(unsigned long long a) { printf("%llu", a); } template void print(const T& a){ cout << a; } int out(){ putchar('\n'); return 0; } template int out(const T& t){ print(t); putchar('\n'); return 0; } template int out(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; } templatevoid print(pair a){print(a.first);print(),print(a.second);} templatevoid print(vector v){for(auto ite=v.begin();ite!=v.end();){print(*ite);if(++ite!=v.end())print();}} templatevoid print(vector> v){for(auto ite=v.begin();ite!=v.end();){print(*ite);if(++ite!=v.end())out();}} void yes(){out("Yes");} void no (){out("No");} void yn (bool t){if(t)yes();else no();} void fast_io(){cin.tie(0); ios::sync_with_stdio(0); cout< dx = {0,1,0,-1,1,1,-1,-1}; const vector dy = {1,0,-1,0,1,-1,-1,1}; const string ALP = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const string alp = "abcdefghijklmnopqrstuvwxyz"; const string NUM = "0123456789"; } // namespace noya2 using namespace noya2; //using mint = modint998244353; using mint = modint1000000007; //using mint = modint; void out(mint a){out(a.val());} void out(vector a){vector b(a.size()); rep(i,a.size()) b[i] = a[i].val(); out(b);} void out(vector> a){for (auto v : a) out(v);} istream &operator>>(istream &is,vector &v){for(auto &e:v){ll _x;is>>_x;e=_x;}return is;} #line 2 "binom.hpp" #line 4 "binom.hpp" namespace noya2{ template struct Binom{ Binom(int lim = 300000){ extend(lim); } static T fact(int x) { if (x < 0) return T(0); extend(x); return kaijo[x]; } static T ifact(int x){ if (x < 0) return T(0); extend(x); return kainv[x]; } static T C(int n, int r){ if (n < 0 || n < r || r < 0) return T(0); extend(n); return kaijo[n] * kainv[r] * kainv[n-r]; } static T P(int n, int r){ if (n < 0 || n < r || r < 0) return T(0); extend(n); return kaijo[n] * kainv[n-r]; } static T H(int n, int r){ if (n < 0 || r < 0) return T(0); return (r == 0 ? T(1) : C(n+r-1,r-1)); } T operator()(int n, int r){ return C(n,r); } template static T M(const Cnts&... cnts){ return multinomial(0,T(1),cnts...); } private: static T multinomial(const int& sum, const T& div_prod){ if (sum < 0) return T(0); return fact(sum) * div_prod; } template static T multinomial(const int& sum, const T& div_prod, const int& n1, const Tail&... tail){ if (n1 < 0) return T(0); return multinomial(sum+n1,div_prod*ifact(n1),tail...); } static std::vector kaijo, kainv; static void extend(int lim){ if (kaijo.empty()){ kaijo = {1,1}; kainv = {1,1}; } int siz = kaijo.size(); if (siz > lim) return ; int nsiz = siz * 2; kaijo.resize(nsiz+1), kainv.resize(nsiz+1); for (int i = siz; i <= nsiz; i++) kaijo[i] = kaijo[i-1] * T(i); kainv[nsiz] = kaijo[nsiz].inv(); for (int i = nsiz-1; i >= siz; i--) kainv[i] = kainv[i+1] * T(i+1); extend(lim); } }; template std::vectorBinom::kaijo = vector(2,T(1)); template std::vectorBinom::kainv = vector(2,T(1)); } // namespace noya2 #line 78 "c.cpp" void solve(){ Binom bnm; int h, w; cin >> h >> w; mint ans = 0; mint ni = 1; for (int i = h; i >= 0; i--){ ans += bnm(h,i) * (ni-1).pow(w) * (i % 2 == 0 ? 1 : -1); ni *= 2; } out(ans); } int main(){ fast_io(); int t = 1; //cin >> t; while(t--) solve(); }