Description



Claris和NanoApe在玩石子游戏,他们有n堆石子,规则如下:


1. Claris和NanoApe两个人轮流拿石子,Claris先拿。


2. 每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜。


不同的初始局面,决定了最终的获胜者,有些局面下先拿的Claris会赢,其余的局面Claris会负。


Claris很好奇,如果这n堆石子满足每堆石子的初始数量是不超过m的质数,而且他们都会按照最优策略玩游戏,那么NanoApe能获胜的局面有多少种。


由于答案可能很大,你只需要给出答案对10^9+7取模的值。


Input



输入文件包含多组数据,以EOF为结尾。


对于每组数据:


共一行两个正整数n和m。



每组数据有1<=n<=10^9, 2<=m<=50000。


不超过80组数据。


Output


 


Sample Input


3 7

4 13


Sample Output


6

120


对于该游戏SG[i]=i


根据SG定理,如果n堆石子的SG异或和为0则后手必胜


问题变成了,从小于m的素数中可重复选n个,异或和为0,有多少方案


当n=2时


可以理解为2个多项式“相乘”


$C[i]=\sum_{j^k=i}A[j]*B[k]$


这是类似与卷积的形式,其实这可以用FWT$O(mlogm)$实现


但不可能我们做n次FWT,因为n最大$10^{9}$


我们发现实际上一次FWT视作一次乘法,就可以看作初始数组$A^{n}$


A[i]=[i是素数]


于是可以快速幂


但实际上没必要在快速幂时用UFWT(逆运算),最后将答案数组UFWT就行了


这样比每次“相乘”时都FWT和UFWT要好了不少,从$O(mlogmlogn)$变成$O(mlogm+mlogn)$



1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #include<cmath>
6 using namespace std;
7 bool vis[50001];
8 int tot,prime[50001],Mod=1e9+7,inv2,n,m;
9 int f[200001],a[200001];
10 void pre()
11 {int i,j;
12 for (i=2;i<=50000;i++)
13 {
14 if (vis[i]==0)
15 {
16 tot++;
17 prime[tot]=i;
18 }
19 for (j=1;j<=tot;j++)
20 {
21 if (i*prime[j]>50000) break;
22 vis[i*prime[j]]=1;
23 if (i%prime[j]==0) break;
24 }
25 }
26 }
27 int qpow(int x,int y)
28 {
29 int res=1;
30 while (y)
31 {
32 if (y&1) res=1ll*res*x%Mod;
33 x=1ll*x*x%Mod;
34 y>>=1;
35 }
36 return res;
37 }
38 void FWT(int *A,int len)
39 {int i,j,k;
40 for (i=1;i<len;i<<=1)
41 {
42 for (j=0;j<len;j+=(i<<1))
43 {
44 for (k=0;k<i;k++)
45 {
46 int x=A[j+k],y=A[j+k+i];
47 A[j+k]=x+y;
48 if (A[j+k]>=Mod) A[j+k]-=Mod;
49 A[j+k+i]=x-y;
50 if (A[j+k+i]<0) A[j+k+i]+=Mod;
51 }
52 }
53 }
54 }
55 void UFWT(int *A,int len)
56 {int i,j,k;
57 for (i=1;i<len;i<<=1)
58 {
59 for (j=0;j<len;j+=(i<<1))
60 {
61 for (k=0;k<i;k++)
62 {
63 int x=A[j+k],y=A[j+k+i];
64 A[j+k]=1ll*(x+y)*inv2%Mod;
65 A[j+k+i]=1ll*(x-y+Mod)*inv2%Mod;
66 }
67 }
68 }
69 }
70 int main()
71 {int len,i;
72 inv2=qpow(2,Mod-2);
73 pre();
74 while (scanf("%d%d",&n,&m)!=EOF)
75 {
76 memset(f,0,sizeof(f));
77 memset(a,0,sizeof(a));
78 len=1;
79 while (len<=m) len*=2;
80 f[0]=1;
81 for (i=1;i<=tot;i++)
82 {
83 if (prime[i]>m) break;
84 a[prime[i]]=1;
85 }
86 FWT(f,len);FWT(a,len);
87 while (n)
88 {
89 if (n&1)
90 {
91 for (i=0;i<len;i++)
92 f[i]=1ll*f[i]*a[i]%Mod;
93 }
94 for (i=0;i<len;i++)
95 a[i]=1ll*a[i]*a[i]%Mod;
96 n>>=1;
97 }
98 UFWT(f,len);
99 printf("%d\n",f[0]);
100 }
101 }