求一个变换 tf ,使得
tf(A⊕B)=tf(A)⋅tf(B)
构造 tf 和逆变换 utf ,
tf(a,b)=(a−b,a+b)
tf(X1,X2)=(tf(X1)−tf(X2),tf(X1)+tf(X2))
tf(A+B)=tf(A)+tf(B)
utf(tf(A))=A
utf(X1,X2)=(utf(X1+X22),utf(X1−X22))
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <set>
#include <ctime>
#include <cstdlib>
using namespace std;
#define inf 0x3f3f3f3f
#define N 800010
#define LL long long
#define mod 1000000007
int qpow(int x, int k) {
int ret = 1;
while(k) {
if(k & 1) ret = 1LL * ret * x % mod;
k >>= 1;
x = 1LL * x * x % mod;
}
return ret;
}
int inv2 = qpow(2, mod - 2);
struct Nim {
int a[N];
void FWT(int l, int r) {
if(l + 1 == r) return;
int l2 = (r - l) / 2;
int m = l + l2;
FWT(l, m); FWT(m, r);
for(int i = l; i < m; ++i) {
int x = a[i];
int y = a[i+l2];
a[i] = x - y; if(a[i] < 0) a[i] += mod;
a[i+l2] = x + y; if(a[i+l2] >= mod) a[i+l2] -= mod;
}
}
void NFWT(int l, int r) {
if(l + 1 == r) return;
int l2 = (r - l) / 2;
int m = l + l2;
for(int i = l; i < m; ++i) {
int x = a[i];
int y = a[i+l2];
a[i] = 1LL * (x + y) * inv2 % mod;
a[i+l2] = 1LL * (x - y) * inv2 % mod;
if(a[i+l2] < 0) a[i+l2] += mod;
}
NFWT(l, m); NFWT(m, r);
}
int count(int K, int L) {
int len = 1 << 16;
for(int i = 2; i < len; ++i) a[i] = 1;
for(int i = 2; i < len; ++i) {
if(i <= L && a[i] == 1) {
for(int j = i + i; j < len; j += i)
a[j] = 0;
}
else a[i] = 0;
}
FWT(0, len);
for(int i = 0; i < len; ++i) a[i] = qpow(a[i], K);
NFWT(0, len);
return a[0];
}
}gao;
int main() {
int k, l;
cin >> k >> l;
cout << gao.count(k, l) << endl;
return 0;
}