#include <bits/stdc++.h>

using namespace std;

class Modular {
private:
    static long long MOD;
    // a * x + b * y == g; g == gcd(x, y)
    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 {  // this doesn't assume prime MOD
        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);
    vector<Modular> twos(m + 1);
    twos[0] = Modular(1);
    for (int i = 1; i <= m; ++i)
        twos[i] = 2 * twos[i - 1];
    vector<Modular> itwos(m + 1);
    itwos[0] = Modular(1);
    for (int i = 1; i <= m; ++i)
        itwos[i] = itwos[i - 1] / 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];
//            for (int p = 2; p <= j; ++p) {
//                dp[i][j] += two.pow(p - 2) * (j - p + 1) * dp[i - 1][j - p + 1];
//            }
            if (j >= 2)
                s += ((j - 1) * dp[i - 1][j - 1]) * itwos[j];
            dp[i][j] += s * twos[j];
        }
    }
    cout << dp[n][m] << "\n";
    return 0;
}
