#include <bits/stdc++.h>
using namespace std;
inline long long read() {
  long long x = 0, f = 1;
  char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-') f = -1;
  for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
  return x * f;
}
const long long MAXN = 100010;
const long long INF = 1e9;
const long long Mod = 1e9 + 7;
long long N;
set<pair<long long, long long> > S;
long long P;
long long last = 0;
long long h[9][MAXN + 1];
long long inv[MAXN + 1];
long long top;
long long f[MAXN + 1];
long long g[9];
pair<long long, long long> sta[MAXN + 1];
const long long inv2 = (Mod + 1) / 2;
inline void Add(long long x, long long fn) {
  if (top && fn == sta[top].second)
    S.erase(sta[top]), sta[top].first = x, S.insert(sta[top]);
  else
    sta[++top] = make_pair(x, fn), S.insert(sta[top]);
}
inline long long Qf(long long x) {
  return (*S.upper_bound(make_pair(x - 1, 3))).second;
}
inline long long OPR(long long i) {
  long long l = 1, r = i + 1, d = (r - l) / 3;
  long long a = Qf(d), b = Qf((r - d) - l), fx = 0;
  fx = 0;
  while (fx == a || fx == b) ++fx;
  return fx;
}
long long ifac[MAXN + 1];
int main() {
  N = read();
  P = read();
  long long now = 2;
  f[1] = f[2] = 0;
  Add(2, 0);
  for (long long i = 3;; i++) {
    long long l = 1, r = i + 1, d = (r - l) / 3;
    long long a = f[d], b = f[(r - d) - l];
    f[i] = 0;
    while (f[i] == a || f[i] == b) ++f[i];
    if (f[i] != f[i - 1]) {
      last = i, Add(i - 1, f[i - 1]);
      if (i > 1000) {
        now = i - 1;
        break;
      }
    }
  }
  long long lena = 1, lenb = 1;
  for (; now <= P;) {
    ++now;
    while (sta[lena].first * 3 < now) ++lena;
    while ((sta[lenb].first * 3) / 2 < now) ++lenb;
    now = max(min((sta[lenb].first * 3 / 2) - 3, sta[lena].first * 3 - 3), now);
    for (long long j = 1; j <= 10; j++) Add(now, OPR(now)), ++now;
  }
  --P;
  for (long long i = 1; i <= top; i++) {
    long long len = min(sta[i].first, P) - min(sta[i - 1].first, P);
    (g[sta[i].second] += len * (P + 1) % Mod -
                         (min(sta[i].first, P) + min(sta[i - 1].first, P) + 1) *
                             len % Mod * inv2 % Mod +
                         Mod) %= Mod;
  }
  inv[1] = 1;
  ifac[0] = 1;
  for (long long i = 2; i <= N; i++)
    inv[i] = (Mod - (Mod / i) * inv[Mod % i] % Mod) % Mod;
  for (long long i = 1; i <= N; i++) ifac[i] = ifac[i - 1] * inv[i] % Mod;
  for (long long i = 0; i < 3; i++) {
    long long ans = 1;
    for (long long j = 0; j <= N; j++) {
      if ((!(j & 1)) || (!i))
        for (long long k = N - j; k >= 0; k--)
          (h[i][k + j] +=
           (i ? h[i - 1][k] : (!k ? 1 : 0)) * ans % Mod * ifac[j] % Mod) %= Mod;
      ans = ans * g[i] % Mod;
    }
  }
  long long fac = 1, pw = 1, sum = (g[0] + g[1] + g[2]) % Mod;
  for (long long i = 1; i <= N; i++) fac = fac * i % Mod, pw = pw * sum % Mod;
  printf("%lld\n", (pw - h[2][N] * fac % Mod + Mod) % Mod);
  return 0;
}
