#include <bits/stdc++.h>
using namespace std;
long long cnt[3], dp[1010][4], n, p;
struct seg {
  long long l, r, v;
  seg() {}
  seg(long long _l, long long _r, long long _v) { l = _l, r = _r, v = _v; }
};
vector<seg> v;
long long cal(long long x, long long y) {
  if (v[x].v != 0 && v[y].v != 0) return 0;
  if (v[x].v != 1 && v[y].v != 1) return 1;
  return 2;
}
long long get(long long x, long long y) {
  if (x % 3 == 0) return -(!(y & 1));
  if (x % 3 == 2) return (y & 1);
  return 0;
}
long long npair(long long a, long long b) {
  return ((a + b) * (a - b + 1) / 2) % 1000000007;
}
void upd(long long& a, long long b) { a = (a + b) % 1000000007; }
int main() {
  cin >> n >> p;
  v.push_back(seg(1, 2, 0));
  long long nxt = 3;
  while (nxt <= p) {
    long long x = nxt / 3, y = nxt - x, id1, id2;
    for (long long i = 0; i < ((long long)(v).size()); i++) {
      if (v[i].l <= x && x <= v[i].r) id1 = i;
      if (v[i].l <= y && y <= v[i].r) id2 = i;
    }
    long long g = cal(id1, id2);
    long long cnt1 = v[id1].r - x + 1;
    long long cnt2 = v[id2].r - y + 1;
    cnt1 = (cnt1 - 1) * 3 + 3 - (nxt % 3);
    cnt2 = cnt2 + cnt2 / 2 + get(nxt, cnt2);
    long long end = nxt + min(cnt1, cnt2) - 1;
    while (!v.empty() && g == v[((long long)(v).size()) - 1].v)
      nxt = v[((long long)(v).size()) - 1].l, v.pop_back();
    v.push_back(seg(nxt, end, g));
    nxt = end + 1;
  }
  for (__typeof((v).begin()) it = (v).begin(); it != (v).end(); it++)
    upd(cnt[it->v], npair(p - it->l, p - min(p, it->r)));
  dp[0][0] = 1;
  for (long long i = 1; i <= n; i++)
    for (long long j = 0; j < 4; j++)
      for (long long k = 0; k < 3; k++)
        upd(dp[i][j], dp[i - 1][j ^ k] * cnt[k]);
  cout << (dp[n][1] + dp[n][2] + dp[n][3]) % 1000000007 << endl;
}
