#include<bits/stdc++.h> #define MAX_N 65536 #define P 1000000007 #define inv2 500000004 usingnamespace std; typedeflonglong lnt; template <classT> inlinevoidread(T &x){ x = 0; int c = getchar(), f = 1; for (; !isdigit(c); c = getchar()) if (c == 45) f = -1; for (; isdigit(c); c = getchar()) (x *= 10) += f*(c-'0'); } int n, m, l, cnt, pri[MAX_N+5]; lnt a[MAX_N+5]; bool NotPri[MAX_N+5]; voidinit(){ NotPri[0] = NotPri[1] = true; for (int i = 2; i <= MAX_N; i++) { if (!NotPri[i]) pri[++cnt] = i; for (int j = 1; j <= cnt; j++) { if (i*pri[j] > MAX_N) break; NotPri[i*pri[j]] = true; if (i%pri[j] == 0) break; } } } lnt pow(lnt x){ lnt ret = 1; for (int k = n; k; k >>= 1, x = x*x%P) if (k&1) ret = ret*x%P; return ret; } voidFWT(lnt *arr, int l){ for (int d = 1; d < l; d <<= 1) for (int i = 0; i < l; i += (d<<1)) for (int j = i; j < i+d; j++) { lnt x = arr[j], y = arr[j+d]; arr[j] = (x+y)%P, arr[j+d] = (x-y+P)%P; } } voidUFWT(lnt *arr, int l){ for (int d = l>>1; d; d >>= 1) for (int i = 0; i < l; i += (d<<1)) for (int j = i; j < i+d; j++) { lnt x = arr[j], y = arr[j+d]; arr[j] = (x+y)%P*inv2%P; arr[j+d] = (x-y+P)%P*inv2%P; } } intmain(){ init(); while (~scanf("%d%d", &n, &m)) { memset(a, 0, sizeof a); for (l = 1; l <= m; l <<= 1) ; for (int i = 1; i <= cnt && pri[i] <= m; i++) a[pri[i]] = 1; FWT(a, l); for (int i = 0; i < l; i++) a[i] = pow(a[i]); UFWT(a, l); printf("%lld\n", a[0]); } return0; }