#include <bits/stdc++.h>
using namespace std;
const double pi = acos(0.0) * 2.0;
const double eps = 1e-12;
const int step[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
template <class T>
inline T abs1(T a) {
  return a < 0 ? -a : a;
}
template <class T>
inline T max1(T a, T b, T c = -1234567, T d = -1234567) {
  T ans = a > b ? a : b;
  if (c != -1234567) ans = max1(ans, c);
  if (d != -1234567) ans = max1(ans, d);
  return ans;
}
template <class T>
inline T min1(T a, T b, T c = -1234567, T d = -1234567) {
  T ans = a < b ? a : b;
  if (c != -1234567) ans = min(ans, c);
  if (d != -1234567) ans = min(ans, d);
  return ans;
}
template <class T>
inline T gcd1(T a, T b) {
  if (a < b) swap(a, b);
  if (a % b == 0) return b;
  return gcd1(b, a % b);
}
template <class T>
inline T lb(T num) {
  return num & (-num);
}
inline int jud(double a, double b) {
  if (abs1(a - b) < eps) return 0;
  if (a < b) return -1;
  return 1;
}
template <class t>
inline int find(t val, t *a, int na, bool f_small = 1, bool f_lb = 1) {
  if (na == 1) return 0;
  int be = 0, en = na - 1;
  if (a[0] <= a[na - 1]) {
    if (f_lb == 0)
      while (be < en) {
        int mid = (be + en + 1) / 2;
        if (jud(a[mid], val) != 1)
          be = mid;
        else
          en = mid - 1;
      }
    else
      while (be < en) {
        int mid = (be + en) / 2;
        if (jud(a[mid], val) != -1)
          en = mid;
        else
          be = mid + 1;
      }
    if (f_small && jud(a[be], val) == 1 && be != 0) be--;
    if (!f_small && jud(a[be], val) == -1 && be != na - 1) be++;
  } else {
    if (f_lb)
      while (be < en) {
        int mid = (be + en + 1) / 2;
        if (jud(a[mid], val) != -1)
          be = mid;
        else
          en = mid - 1;
      }
    else
      while (be < en) {
        int mid = (be + en) / 2;
        if (jud(a[mid], val) != 1)
          en = mid;
        else
          be = mid + 1;
      }
    if (!f_small && jud(a[be], val) == -1 && be != 0) be--;
    if (f_small && jud(a[be], val) == 1 && be != na - 1) be++;
  }
  return be;
}
inline int bitnum(unsigned long long nValue) {
  nValue = ((0xaaaaaaaaaaaaaaaaull & nValue) >> 1) +
           (0x5555555555555555ull & nValue);
  nValue = ((0xccccccccccccccccull & nValue) >> 2) +
           (0x3333333333333333ull & nValue);
  nValue = ((0xf0f0f0f0f0f0f0f0ull & nValue) >> 4) +
           (0x0f0f0f0f0f0f0f0full & nValue);
  nValue = ((0xff00ff00ff00ff00ull & nValue) >> 8) +
           (0x00ff00ff00ff00ffull & nValue);
  nValue = ((0xffff0000ffff0000ull & nValue) >> 16) +
           (0x0000ffff0000ffffull & nValue);
  nValue = ((0xffffffff00000000ull & nValue) >> 32) +
           (0x00000000ffffffffull & nValue);
  return nValue;
}
long long pow(long long n, long long m, long long mod = 0) {
  long long ans = 1;
  long long k = n;
  while (m) {
    if (m & 1) {
      ans *= k;
      if (mod) ans %= mod;
    }
    k *= k;
    if (mod) k %= mod;
    m >>= 1;
  }
  return ans;
}
const int maxn = 1000000;
const int mod = 1000000007;
int jie[maxn][2], ljie;
int n, p;
int main() {
  jie[0][1] = 0;
  jie[0][0] = 2;
  jie[1][1] = 1;
  jie[1][0] = 3;
  ljie = 2;
  scanf("%d%d", &n, &p);
  for (int num1 = 1, num2 = 3, link1 = 0, link2 = 1;
       jie[ljie - 1][0] < p - 1;) {
    int link11, link22;
    link11 = link1;
    link22 = link2;
    if (jie[link11][1] > 0 && jie[link22][1] > 0) {
      while (link11 < ljie && jie[link11][1] > 0) link11++;
      if (jie[link11][1] == 0) link11--;
      while (link22 < ljie && jie[link22][1] > 0) link22++;
      if (jie[link22][1] == 0) link22--;
    }
    jie[ljie][1] = 0;
    while (jie[ljie][1] == jie[link22][1] || jie[ljie][1] == jie[link11][1])
      jie[ljie][1]++;
    jie[ljie][0] = jie[link11][0] * 3 + 2;
    jie[ljie][0] = min1(jie[ljie][0], jie[link22][0] + jie[link22][0] / 2);
    num1 = (jie[ljie][0] + 1) / 3;
    num2 = jie[ljie][0] + 1 - (jie[ljie][0] + 1) / 3;
    while (jie[link1][0] < num1) link1++;
    while (jie[link2][0] < num2) link2++;
    if (jie[ljie][1] != jie[ljie - 1][1])
      ljie++;
    else
      jie[ljie - 1][0] = jie[ljie][0];
  }
  if (p < 3) {
    cout << 0 << endl;
    return 0;
  }
  long long can[4] = {0};
  can[0] += (long long)p * 2 - 3;
  can[0] %= mod;
  for (int i = 1; i < ljie - 1; i++) {
    can[jie[i][1]] += (long long)p * (jie[i][0] - jie[i - 1][0]) -
                      (long long)(jie[i][0] - jie[i - 1][0]) *
                          (jie[i][0] + jie[i - 1][0] + 1) / 2;
    can[jie[i][1]] %= mod;
  }
  can[jie[ljie - 1][1]] +=
      (long long)p * (p - 1 - jie[ljie - 2][0]) -
      (long long)(p - 1 - jie[ljie - 2][0]) * (p + jie[ljie - 2][0]) / 2;
  can[jie[ljie - 1][1]] %= mod;
  long long ans[4] = {0};
  ans[0] = 1;
  long long rans[4] = {0};
  for (int i = 0; i < n; i++) {
    memset(rans, 0, sizeof(rans));
    for (int j = 0; j < 4; j++)
      for (int k = 0; k < 4; k++) {
        rans[j ^ k] += ans[j] * can[k];
        rans[j ^ k] %= mod;
      }
    memcpy(ans, rans, sizeof(ans));
  }
  cout << (ans[1] + ans[2] + ans[3]) % mod << endl;
  return 0;
}
