#include <bits/stdc++.h>
using namespace std;

#define REP(i,n) for(int i=0;i<(n);i++)
#define ALL(v) v.begin(),v.end()

#define int long long
const int MOD=998244353;

int dp[15][1000001];
int pw(int n,int k){
  assert(k>=0);
  int res=1;
  while(k){
    if(k&1)(res*=n)%=MOD;
    (n*=n)%=MOD;
    k>>=1;
  }
  return res;
}
int Factorial[5000000],Finverse[5000000];
inline void Cinit(){
  Factorial[0]=1;
  for(int i=1;i<5e6;i++)Factorial[i]=(Factorial[i-1]*i)%MOD;
  Finverse[4999999]=pw(Factorial[4999999],MOD-2);
  for(int i=4999998;i>=0;i--)Finverse[i]=(i+1)*Finverse[i+1]%MOD;
}

int memo[5001][5001];
int nCk(int n,int k){
  if(n<k)return 0;if(k<0)return 0;
  if(!Factorial[0])Cinit();
  if(~memo[n][k])return memo[n][k];
  int res=Factorial[n];
  (res*=Finverse[k])%=MOD;
  (res*=Finverse[n-k])%=MOD;
  return memo[n][k]=res;
}

signed main(){
  memset(memo,-1,sizeof(memo));
  int n,m;cin>>n>>m;
  dp[0][0]=1;
  for(int i=0;i<14;i++){
    for(int j=0;j<1000000;j++){
      if(((m>>i)&1)^(j&1))continue;
      if(dp[i][j]==0)continue;
      int s=j/2;//上に繰り上がる予約
      for(int k=0;2*k<=n;k++){//k新たに繰り上げる
        //n個のうち2k個が1
        (dp[i+1][s+k]+=dp[i][j]*nCk(n,2*k)%MOD)%=MOD;
      }
    }
  }
  cout<<dp[14][0]<<endl;
}

#include<bits/stdc++.h>
using namespace std;
#define M 5005
#define K 13
#define MOD 998244353

int comb[M][M];
int dp[K][M];

int main()
{
    for(int i = 0; i < M; i++) comb[i][0] = 1;
    for(int i = 1; i < M; i++)
    {
        for(int j = 1; j <= i; j++) comb[i][j] = (comb[i-1][j]+comb[i-1][j-1])%MOD;
    }

    int n, m;
    scanf("%d %d", &n, &m);

    for(int j = 0; j <= min(n, m); j += 2) dp[0][j] = comb[n][j];
    for(int i = 1; i < K; i++)
    {
        for(int j = 0; j <= m; j++)
        {
            for(int k = 0; k <= n && (1<<i)*k <= j; k += 2)
            {
                dp[i][j] += 1LL*comb[n][k]*dp[i-1][j-(1<<i)*k]%MOD;
                if(dp[i][j] >= MOD) dp[i][j] -= MOD;
            }
        }
    }

    int ans = dp[K-1][m];
    printf("%d\n", ans);

    return 0;
}
