#include <bits/stdc++.h>
using namespace std;
class Modular {
 private:
  static long long MOD;
  static void extended_gcd(long long x, long long y, long long& a, long long& b,
                           long long& g) {
    if (x < 0) {
      extended_gcd(-x, y, a, b, g);
      a = -a;
    } else if (y < 0) {
      extended_gcd(x, -y, a, b, g);
      b = -b;
    } else if (x > y) {
      extended_gcd(y, x, b, a, g);
    } else if (x == 0) {
      a = 0;
      b = 1;
      g = y;
    } else {
      long long a1 = -1;
      long long b1 = -1;
      extended_gcd(y % x, x, a1, b1, g);
      b = a1;
      a = b1 - a1 * (y / x);
    }
  }
  static long long mod_inv(long long x, long long m) {
    long long a = 0;
    long long b = 0;
    long long g = 0;
    extended_gcd(x, m, a, b, g);
    a = ((a % m) + m) % m;
    return a;
  }

 public:
  long long value;
  Modular() : value(0) {}
  explicit Modular(long long v) : value(normalize(v)) {}
  static long long normalize(long long v) {
    v = v % MOD;
    if (v < 0) v += MOD;
    return v;
  }
  bool operator==(const Modular& a) const { return value == a.value; }
  bool operator<(const Modular& a) const { return value < a.value; }
  Modular operator+=(const Modular& a) {
    value = normalize(value + a.value);
    return *this;
  }
  Modular operator-=(const Modular& a) {
    value = normalize(value - a.value);
    return *this;
  }
  Modular operator*=(const Modular& a) {
    value = normalize(value * a.value);
    return *this;
  }
  Modular operator/=(const Modular& a) { return (*this) *= a.inv(); }
  Modular operator++() {
    value = normalize(value + 1);
    return *this;
  }
  Modular operator--() {
    value = normalize(value - 1);
    return *this;
  }
  Modular operator++(int) {
    Modular tmp = *this;
    value = normalize(value + 1);
    return tmp;
  }
  Modular operator--(int) {
    Modular tmp = *this;
    value = normalize(value - 1);
    return tmp;
  }
  template <typename T>
  Modular operator+=(const T& a) {
    value = normalize(value + a);
    return *this;
  }
  template <typename T>
  Modular operator-=(const T& a) {
    value = normalize(value - a);
    return *this;
  }
  template <typename T>
  Modular operator*=(const T& a) {
    value = normalize(value * a);
    return *this;
  }
  Modular inv() const { return Modular(mod_inv(value, MOD)); }
  Modular pow(long long p) const {
    Modular res(1);
    Modular sq(value);
    while (p > 0) {
      if (p % 2 == 1) {
        res *= sq;
      }
      sq *= sq;
      p /= 2;
    }
    return res;
  }
  static void set_mod(long long mod) { MOD = mod; }
};
long long Modular::MOD = 0;
Modular operator+(const Modular& a, const Modular& b) {
  Modular c(a);
  return c += b;
}
template <typename T>
Modular operator+(const Modular& a, const T& b) {
  return a + Modular(b);
}
template <typename T>
Modular operator+(const T& a, const Modular& b) {
  return Modular(a) + b;
}
Modular operator-(const Modular& a, const Modular& b) {
  Modular c(a);
  return c -= b;
}
template <typename T>
Modular operator-(const Modular& a, const T& b) {
  return a - Modular(b);
}
template <typename T>
Modular operator-(const T& a, const Modular& b) {
  return Modular(a) - b;
}
Modular operator*(const Modular& a, const Modular& b) {
  Modular c(a);
  return c *= b;
}
template <typename T>
Modular operator*(const Modular& a, const T& b) {
  return a * Modular(b);
}
template <typename T>
Modular operator*(const T& a, const Modular& b) {
  return Modular(a) * b;
}
Modular operator/(const Modular& a, const Modular& b) {
  Modular c(a);
  return c /= b;
}
template <typename T>
Modular operator/(const Modular& a, const T& b) {
  return a / Modular(b);
}
template <typename T>
Modular operator/(const T& a, const Modular& b) {
  return Modular(a) / b;
}
std::ostream& operator<<(std::ostream& os, const Modular& m) {
  return os << m.value;
}
std::istream& operator>>(std::istream& is, Modular& m) { return is >> m.value; }
int main() {
  Modular::set_mod(1000000007);
  int n, m;
  cin >> n >> m;
  vector<vector<Modular>> dp(n + 1, vector<Modular>(m + 1));
  for (int i = 0; i <= m; ++i) {
    dp[0][i] = Modular(1);
    if (i == 0)
      dp[1][i] = Modular(1);
    else
      dp[1][i] = 2 * dp[1][i - 1];
  }
  Modular two(2);
  for (int i = 2; i <= n; ++i) {
    Modular s;
    for (int j = 0; j <= m; ++j) {
      dp[i][j] = (j + 1) * dp[i - 1][j];
      if (j >= 2) s += ((j - 1) * dp[i - 1][j - 1]) / two.pow(j);
      dp[i][j] += s * two.pow(j);
    }
  }
  cout << dp[n][m] << "\n";
  return 0;
}
