#include <bits/stdc++.h>
using namespace std;
const int inf = ~0U >> 1;
const long long INF = ~0ULL >> 1;
;
const double pi = acos(-1.0);
template <class T>
inline T sqr(T a) {
  return a * a;
}
template <class T>
inline void read(T &n) {
  char c;
  for (c = getchar(); !(c >= '0' && c <= '9'); c = getchar())
    ;
  n = c - '0';
  for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0';
}
int Pow(int base, int n, int mo) {
  if (n == 0) return 1;
  if (n == 1) return base;
  int tmp = Pow(base, n >> 1, mo);
  tmp = (long long)tmp * tmp % mo;
  if (n & 1) tmp = (long long)tmp * base % mo;
  return tmp;
}
struct point {
  int x, y;
  point() {}
  point(int _x, int _y) : x(_x), y(_y) {}
};
const int sg[103][2] = {
    {0, 0},         {2, 0},         {3, 1},         {4, 2},
    {6, 1},         {8, 2},         {12, 0},        {14, 1},
    {18, 2},        {26, 0},        {38, 1},        {39, 2},
    {56, 0},        {57, 2},        {80, 1},        {84, 2},
    {119, 0},       {120, 2},       {173, 1},       {178, 2},
    {254, 0},       {259, 2},       {362, 1},       {381, 2},
    {536, 0},       {543, 2},       {779, 1},       {804, 2},
    {1145, 0},      {1168, 2},      {1631, 1},      {1717, 2},
    {2414, 0},      {2446, 2},      {3506, 1},      {3621, 2},
    {5153, 0},      {5259, 2},      {7340, 1},      {7729, 2},
    {10865, 0},     {11010, 2},     {15779, 1},     {16297, 2},
    {23189, 0},     {23668, 2},     {33032, 1},     {34783, 2},
    {48893, 0},     {49548, 2},     {71006, 1},     {73339, 2},
    {104351, 0},    {106509, 2},    {148646, 1},    {156526, 2},
    {220019, 0},    {222969, 2},    {319529, 1},    {330028, 2},
    {469580, 0},    {479293, 2},    {668909, 1},    {704370, 2},
    {990086, 0},    {1003363, 2},   {1437881, 1},   {1485129, 2},
    {2113112, 0},   {2156821, 2},   {3010091, 1},   {3169668, 2},
    {4455389, 0},   {4515136, 2},   {6470465, 1},   {6683083, 2},
    {9509006, 0},   {9705697, 2},   {13545410, 1},  {14263509, 2},
    {20049251, 0},  {20318115, 2},  {29117093, 1},  {30073876, 2},
    {42790529, 0},  {43675639, 2},  {60954347, 1},  {64185793, 2},
    {90221630, 0},  {91431520, 2},  {131026919, 1}, {135332445, 2},
    {192557381, 0}, {196540378, 2}, {274294562, 1}, {288836071, 2},
    {405997337, 0}, {411441843, 2}, {589621136, 1}, {608996005, 2},
    {866508215, 0}, {884431704, 2}, {1000000000, 1}};
const int mo = 1000000007;
long long Cnt[3];
int dp[2000][4], n, p;
int main() {
  scanf("%d%d", &n, &p);
  for (int i = (1); i <= (102); ++i) {
    int top = min(sg[i][0], p);
    long long cnt = (long long)(p) * (top - sg[i - 1][0]);
    cnt -= (long long)(sg[i - 1][0] + 1 + top) * (top - sg[i - 1][0]) / 2;
    Cnt[sg[i][1]] = (Cnt[sg[i][1]] + cnt) % mo;
    if (sg[i][0] > p) break;
  }
  dp[0][0] = 1;
  for (int i = (1); i <= (n); ++i) {
    for (int j = (0); j <= (2); ++j)
      for (int k = (0); k <= (3); ++k)
        dp[i][j ^ k] =
            ((long long)dp[i][j ^ k] + (long long)Cnt[j] * dp[i - 1][k]) % mo;
  }
  printf("%d\n", ((long long)dp[n][1] + dp[n][2] + dp[n][3]) % mo);
  return 0;
}
