//BadWaperZ
#include<bits/stdc++.h>
#define inf 1e9
#define eps 1e-6
#define mp make_pair
#define pb push_back
#define fr first
#define sd second
#define pa pair<ll,ll>
#define re register ll
#define FOR(i,a,b) for(re i=a;i<=b;i++)
#define REP(i,a,b) for(re i=a;i>=b;i--)
#define MEM(a) memset(a,0,sizeof(a))
#define N 5010
#define M 21
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
inline ll read()
{
	char ch=getchar();
	ll s=0,w=1;
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
	return s*w;
}
inline ll lowbit(ll x){return x&(-x);}
const ll mod=998244353;
ll f[M][N],C[N][N];
ll n,m;
inline ll Z(ll x){return (x>=mod?x-mod:x);}
int main()
{
	//ios::sync_with_stdio(false);
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	n=read(),m=read();
	C[0][0]=1;
	FOR(i,1,n){C[i][0]=1;FOR(j,1,i)C[i][j]=Z(C[i-1][j]+C[i-1][j-1]);}
	f[0][0]=1;ll t=0;
	FOR(k,1,20)
	{
		int v=(1<<(k-1));
		if(v>m){t=k-1;break;}
		FOR(s,0,m)if(f[k-1][s])for(re j=0;j<=n;j+=2)
		{
			if(s+j*v>m)break;
			f[k][s+j*v]=Z(f[k][s+j*v]+1LL*f[k-1][s]*C[n][j]%mod);
		}
	}
	cout<<f[t][m]<<'\n';
	return 0;
}


#include <bits/stdc++.h>          
using namespace std;
using ll = long long;
using ld = long double;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define repp(i, st, en) for (ll i = (ll)st; i < (ll)(en); i++)
#define repm(i, st, en) for (ll i = (ll)st; i >= (ll)(en); i--)
#define all(v) v.begin(), v.end()
void chmax(ll &x, ll y) {x = max(x,y);}
void chmin(ll &x, ll y) {x = min(x,y);}
void Yes() {cout << "Yes" << endl; exit(0);}
void No() {cout << "No" << endl; exit(0);}
template<class in_Cout> void Cout(in_Cout x) {cout << x << endl; exit(0);}
template<class in_vec_cout>
void vec_cout(vector<in_vec_cout> vec) {
    for (in_vec_cout res : vec) {cout << res << " ";}
    cout << endl;
}

const ll inf = 1e18;
const ll mod = 998244353;
const ll logM = 16;

ll N, M;

vector<ll> to_bin(ll N) {
    vector<ll> res(logM);
    vector<ll> tmp;
    while (N>0) {
        tmp.push_back(N%2);
        N /= 2;
    }
    rep(i,tmp.size()) res[i] = tmp[i];
    return res;
}

// nCr (mod p) 計算量 O(3*10^5*logp)
const ll Maximum = 3e5;
ll Fac[Maximum+1], iFac[Maximum+1];
bool made_Fac = false;
// x^n (mod p) 計算量 O(logn)
ll powmodp(ll x, ll n) {
    if (n==0) return 1;
    else if (n%2==0) {
        ll ans = powmodp(x,n/2);
        return ans*ans % mod;
    }
    else return x * powmodp(x,n-1) % mod;
}
// nCr (mod p) 計算量 O(3*10^5*logp)
void make_Fac() {
    Fac[0] = 1;
    iFac[0] = 1;
    for (ll i=0; i<Maximum; i++) {
        Fac[i+1] = Fac[i] * (i+1) % mod;
        iFac[i+1] = iFac[i] * powmodp(i+1,mod-2) % mod;
    }
}
ll nCrmodp(ll n, ll r) {
    if (!made_Fac) {
        make_Fac();
        made_Fac = true;
    }
    r = min(r,n-r);
    if (n==0 or r==0) return 1;
    ll tmp = iFac[n-r] * iFac[r] % mod;
    return tmp * Fac[n] % mod;
}

int main() {
    cin >> N >> M;

    if (M%2) Cout(0);

    vector<ll> S = to_bin(M);

    vector<vector<ll>> dp(logM,vector<ll>(M+1));
    for (ll i=0; i<=N; i+=2) {
        ll up = i/2;
        if (up>M) continue;
        dp[0][up] = nCrmodp(N,i);
    }
    for (ll i=1; i<logM; i++) {
        for (ll k=0; k<=N; k+=2) {
            ll cnt = nCrmodp(N,k);
            for (ll j=0; j<=M; j++) {
                if (S[i]!=j%2) continue;
                ll up = (k + j)/2;
                if (up>M) continue;
                dp[i][up] += cnt * dp[i-1][j] % mod;
                dp[i][up] %= mod;
            }
        }
    }

    ll ans = dp.back()[0];

    cout << ans << endl;
}