#include <bits/stdc++.h>
#pragma optimize("Ofast")
using namespace std;
int const MOD = 1e9 + 7;
int const MAX = 1e3 + 41;
int add(int a, int b) {
  a += b;
  if (a >= MOD) a -= MOD;
  return a;
}
int mult(int a, int b) { return (long long)a * b % MOD; }
int C[MAX][MAX];
void init() {
  for (int i = 0; i <= MAX - 1; i++) {
    C[i][0] = 1;
    for (int j = 1; j <= i; j++) {
      C[i][j] = add(C[i - 1][j - 1], C[i - 1][j]);
    }
  }
}
vector<int> a;
int n;
int const INF = 1e9 + 41;
int const MAGIC = 6e7 + 41;
int const STEP = 1e4 + 41;
int g[MAGIC];
int mex(int a, int b) {
  if (a != 0 && b != 0) return 0;
  if (a != 1 && b != 1) return 1;
  return 2;
}
int brute(int x) {
  if (x < MAGIC) {
    return g[x];
  }
  return mex(brute(x / 3), brute(x - x / 3));
}
int const INV2 = (MOD + 1) / 2;
int getsum(int a, int b) {
  int q = (b - a + 1);
  return mult(q, mult(add(a, b), INV2));
}
int ds[3];
int d[4][4][MAX];
int k;
void solve() {
  for (int i = 3; i <= MAGIC - 1; i++) {
    int g1 = g[i / 3];
    int g2 = g[i - i / 3];
    g[i] = mex(g1, g2);
  }
  int lst = 1;
  a.push_back(1);
  for (int i = 1; i <= MAGIC - 1; i++) {
    if (g[i] != g[lst]) {
      a.push_back(i);
      lst = i;
    }
  }
  lst = MAGIC - 1;
  a.push_back(lst);
  while (lst < n) {
    int nxt = min(n, lst + STEP);
    int cur = brute(lst);
    if (brute(nxt) != cur) {
      int l = lst;
      int r = nxt + 1;
      while (r - l > 1) {
        int h = (l + r) / 2;
        if (brute(h) != cur) {
          r = h;
        } else {
          l = h;
        }
      }
      lst = r;
      a.push_back(lst);
    } else {
      lst = nxt;
    }
  }
  a.push_back(lst);
  a.push_back(n);
  sort(a.begin(), a.end());
  a.resize(unique(a.begin(), a.end()) - a.begin());
  while ((int)a.size() && a.back() > n) {
    a.pop_back();
  }
  vector<int> vg;
  for (int i = 0; i <= (int)a.size() - 1; i++) {
    vg.push_back(brute(a[i]));
  }
  for (int i = 0; i <= (int)a.size() - 2; i++) {
    int l = a[i];
    int r = a[i + 1] - 1;
    int wl = n - l;
    int wr = n - r;
    int w = getsum(wr, wl);
    ds[vg[i]] = add(ds[vg[i]], w);
  }
  d[0][0][0] = 1;
  for (int i = 0; i <= 2; i++) {
    for (int o = 0; o <= 3; o++) {
      for (int j = 0; j <= k; j++) {
        int v2 = 1;
        for (int take = 0; take <= k - j; take++, v2 = mult(v2, ds[i])) {
          int ni = i + 1;
          int no = o;
          if (i && take % 2 == 1) {
            no = (no ^ i);
          }
          int nj = take + j;
          int v1 = C[k - j][take];
          int v3 = d[i][o][j];
          int v = mult(v1, mult(v2, v3));
          d[ni][no][nj] = add(d[ni][no][nj], v);
        }
      }
    }
  }
  int ans = 0;
  for (int i = 1; i <= 3; i++) {
    ans = add(ans, d[3][i][k]);
  }
  printf("%d\n", ans);
}
int main() {
  init();
  scanf("%d %d", &k, &n);
  solve();
  return 0;
}
