func_code_string: #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;   }   