#include <bits/stdc++.h>
using namespace std;
const long long int K = 1e9 + 7;
long long int mu(long long int a, long long int n) {
  if (n == 0) return 1;
  long long int q = mu(a, n / 2);
  if (n % 2 == 0) return q * q % K;
  return q * q % K * a % K;
}
const int MaxN = 100005;
long long int inv[MaxN];
long long int n, k;
namespace Poly {
inline void fft(vector<complex<double> > &a, bool inv) {
  int n = a.size(), j = 0;
  vector<complex<double> > roots(n / 2);
  for (int i = 1; i < n; i++) {
    int bit = (n >> 1);
    while (j >= bit) {
      j -= bit;
      bit >>= 1;
    }
    j += bit;
    if (i < j) swap(a[i], a[j]);
  }
  double ang = 2 * acos(-1) / n * (inv ? -1 : 1);
  for (int i = 0; i < n / 2; i++) {
    roots[i] = complex<double>(cos(ang * i), sin(ang * i));
  }
  for (int i = 2; i <= n; i <<= 1) {
    int step = n / i;
    for (int j = 0; j < n; j += i) {
      for (int k = 0; k < i / 2; k++) {
        complex<double> u = a[j + k], v = a[j + k + i / 2] * roots[step * k];
        a[j + k] = u + v;
        a[j + k + i / 2] = u - v;
      }
    }
  }
  if (inv)
    for (int i = 0; i < n; i++) a[i] /= n;
}
inline vector<long long int> multiply(vector<long long int> &v,
                                      vector<long long int> &w) {
  vector<complex<double> > fv(v.begin(), v.end()), fw(w.begin(), w.end());
  int n = 2;
  while (n < v.size() + w.size()) n <<= 1;
  fv.resize(n);
  fw.resize(n);
  fft(fv, 0);
  fft(fw, 0);
  for (int i = 0; i < n; i++) fv[i] *= fw[i];
  fft(fv, 1);
  n = v.size() + w.size() - 1;
  vector<long long int> ret(n);
  for (int i = 0; i < n; i++) ret[i] = (long long int)round(fv[i].real());
  return ret;
}
inline vector<long long int> multiply(vector<long long int> &v,
                                      vector<long long int> &w,
                                      long long int mod) {
  int n = 2;
  while (n < v.size() + w.size()) n <<= 1;
  vector<complex<double> > v1(n), v2(n), r1(n), r2(n);
  for (int i = 0; i < v.size(); i++) {
    v1[i] = complex<double>(v[i] >> 15, v[i] & 32767);
  }
  for (int i = 0; i < w.size(); i++) {
    v2[i] = complex<double>(w[i] >> 15, w[i] & 32767);
  }
  fft(v1, 0);
  fft(v2, 0);
  for (int i = 0; i < n; i++) {
    int j = (i ? (n - i) : i);
    complex<double> ans1 = (v1[i] + conj(v1[j])) * complex<double>(0.5, 0);
    complex<double> ans2 = (v1[i] - conj(v1[j])) * complex<double>(0, -0.5);
    complex<double> ans3 = (v2[i] + conj(v2[j])) * complex<double>(0.5, 0);
    complex<double> ans4 = (v2[i] - conj(v2[j])) * complex<double>(0, -0.5);
    r1[i] = (ans1 * ans3) + (ans1 * ans4) * complex<double>(0, 1);
    r2[i] = (ans2 * ans3) + (ans2 * ans4) * complex<double>(0, 1);
  }
  fft(r1, 1);
  fft(r2, 1);
  n = v.size() + w.size() - 1;
  n = min(n, (int)k + 1);
  vector<long long int> ret(n);
  for (int i = 0; i < n; i++) {
    long long int av = (long long int)round(r1[i].real());
    long long int bv =
        (long long int)round(r1[i].imag()) + (long long int)round(r2[i].real());
    long long int cv = (long long int)round(r2[i].imag());
    av %= mod, bv %= mod, cv %= mod;
    ret[i] = (av << 30) + (bv << 15) + cv;
    ret[i] %= mod;
    ret[i] += mod;
    ret[i] %= mod;
  }
  return ret;
}
inline vector<long long int> multiply_modx(vector<long long int> &v,
                                           vector<long long int> &w,
                                           long long int mod, int k) {
  int n = 2;
  while (n < v.size() + w.size()) n <<= 1;
  vector<complex<double> > v1(n), v2(n), r1(n), r2(n);
  for (int i = 0; i < v.size(); i++) {
    v1[i] = complex<double>(v[i] >> 15, v[i] & 32767);
  }
  for (int i = 0; i < w.size(); i++) {
    v2[i] = complex<double>(w[i] >> 15, w[i] & 32767);
  }
  fft(v1, 0);
  fft(v2, 0);
  for (int i = 0; i < n; i++) {
    int j = (i ? (n - i) : i);
    complex<double> ans1 = (v1[i] + conj(v1[j])) * complex<double>(0.5, 0);
    complex<double> ans2 = (v1[i] - conj(v1[j])) * complex<double>(0, -0.5);
    complex<double> ans3 = (v2[i] + conj(v2[j])) * complex<double>(0.5, 0);
    complex<double> ans4 = (v2[i] - conj(v2[j])) * complex<double>(0, -0.5);
    r1[i] = (ans1 * ans3) + (ans1 * ans4) * complex<double>(0, 1);
    r2[i] = (ans2 * ans3) + (ans2 * ans4) * complex<double>(0, 1);
  }
  fft(r1, 1);
  fft(r2, 1);
  if (n > k + 1) n = k + 1;
  vector<long long int> ret(n);
  for (int i = 0; i < n; i++) {
    long long int av = (long long int)round(r1[i].real());
    long long int bv =
        (long long int)round(r1[i].imag()) + (long long int)round(r2[i].real());
    long long int cv = (long long int)round(r2[i].imag());
    av %= mod, bv %= mod, cv %= mod;
    ret[i] = (av << 30) + (bv << 15) + cv;
    ret[i] %= mod;
    ret[i] += mod;
    ret[i] %= mod;
  }
  return ret;
}
inline vector<long long int> inverse(vector<long long int> &v, int m) {
  int n = 1;
  vector<long long int> R, V, G;
  R.push_back(mu(v[0], K - 2));
  V.push_back(v[0]);
  while (n <= m) {
    n <<= 1;
    for (int i = n / 2; i < v.size() && i < n; i++) V.push_back(v[i]);
    G = multiply(R, R, K);
    G = multiply_modx(G, V, K, n - 1);
    for (int i = n / 2; i <= n - 1; i++) {
      R.push_back((-G[i] + K) % K);
    }
  }
  R.resize(m + 1);
  return R;
}
inline vector<long long int> sqrt(vector<long long int> &v, int m) {
  assert(v[0] == 1 || v[0] == 0);
  long long int rev2 = mu(2, K - 2);
  int n = 1;
  vector<long long int> V, R, G, P;
  R.push_back(v[0]);
  V.push_back(v[0]);
  n = 1;
  while (n <= m) {
    n <<= 1;
    for (int i = n / 2; i < v.size() && i < n; i++) V.push_back(v[i]);
    G = inverse(R, n - 1);
    G = multiply_modx(G, V, K, n - 1);
    for (int i = n / 2; i < n; i++) {
      R.push_back(G[i] * rev2 % K);
    }
  }
  R.resize(m + 1);
  return R;
}
inline vector<long long int> derivative(vector<long long int> &a, int m) {
  vector<long long int> b;
  for (long long int i = 0; i + 1 < a.size(); i++) {
    b.push_back(a[i + 1] * (i + 1) % K);
  }
  return b;
}
inline vector<long long int> integrate(vector<long long int> &a, int m) {
  vector<long long int> b;
  b.push_back(0);
  for (long long int i = 1; i - 1 < a.size() && i <= m; i++) {
    b.push_back(a[i - 1] * inv[i] % K);
  }
  return b;
}
vector<long long int> ln(vector<long long int> &a, int m) {
  vector<long long int> b = inverse(a, m);
  vector<long long int> c = derivative(a, m);
  b = multiply_modx(b, c, K, m);
  b = integrate(b, m);
  return b;
}
vector<long long int> exp(vector<long long int> &v, int m) {
  assert(v.size() > 1);
  int n = 1;
  vector<long long int> R, G;
  R.push_back(1);
  while (n <= m) {
    n <<= 1;
    G = ln(R, n - 1);
    for (int i = 0; i < n && i <= m; i++) G[i] = (v[i] - G[i] + K) % K;
    G[0]++;
    R = multiply_modx(R, G, K, n - 1);
  }
  R.resize(m + 1);
  return R;
}
vector<long long int> pw(vector<long long int> &a, int n, int m) {
  vector<long long int> res;
  if (n == 0) {
    res.push_back(1);
    return res;
  }
  long long int M = mu(a[0], n);
  res = ln(a, m);
  for (int i = 0; i <= m; i++) res[i] = res[i] * n % K;
  res = exp(res, m);
  for (int i = 0; i <= m; i++) res[i] = res[i] * M % K;
  return res;
}
};  // namespace Poly
using namespace Poly;
vector<long long int> A, E;
long long int gt[60005], rev[60005];
long long int Combi(long long int n, long long int k) {
  if (n < k) return 0;
  return gt[n] * rev[n - k] % K * rev[k] % K;
}
vector<long long int> solve(long long int n) {
  if (n == 1) return E;
  vector<long long int> Q = solve(n / 2);
  if (n % 2 == 0) {
    vector<long long int> P(k + 1);
    long long int u = mu(2, n / 2);
    long long int u1 = 1;
    for (int i = 0; i < Q.size(); i++) {
      P[i] = u1 * Q[i] % K;
      u1 = u1 * u % K;
    }
    return multiply(P, Q, K);
  } else {
    vector<long long int> P(k + 1);
    long long int u = 1;
    for (int i = 0; i < Q.size(); i++) {
      P[i] = Q[i] * u % K;
      u = u * 2 % K;
    }
    P = multiply(P, E, K);
    u = mu(2, n / 2);
    long long int u1 = 1;
    for (int i = 0; i < Q.size(); i++) {
      P[i] = u1 * P[i] % K;
      u1 = u1 * u % K;
    }
    return multiply(P, Q, K);
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(NULL);
  inv[1] = 1;
  for (int i = 2; i <= 100000; i++) inv[i] = (K - K / i) * 1ll * inv[K % i] % K;
  gt[0] = rev[0] = 1;
  for (int i = 1; i <= 60000; i++) {
    gt[i] = gt[i - 1] * 1ll * i % K;
    rev[i] = rev[i - 1] * inv[i] % K;
  }
  cin >> n >> k;
  if (n > k) {
    cout << 0;
    return 0;
  }
  E.resize(k + 1);
  for (int i = 1; i <= k; i++) E[i] = rev[i] % K;
  A = solve(n);
  long long int res = 0;
  for (int i = 0; i <= k; i++) {
    res = (res + Combi(k, i) * A[i] % K * gt[i] % K) % K;
  }
  cout << res << endl;
  return 0;
}
