#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
using namespace std;
#define endl "\n"
#define ll long long
#define sz(s) (int)(s.size())
#define INF 0x3f3f3f3f3f3f3f3fLL
#define all(v) v.begin(),v.end()
#define watch(x) cout<<(#x)<<" = "<<x<<endl
const int dr[] { -1, -1, 0, 1, 1, 1, 0, -1 };
const int dc[] { 0, 1, 1, 1, 0, -1, -1, -1 };
#if __cplusplus >= 201402L
template<typename T>
vector<T> create(size_t n) {
	return vector<T>(n);
}
template<typename T, typename ... Args>
auto create(size_t n, Args ... args) {
	return vector<decltype(create<T>(args...))>(n, create<T>(args...));
}
#endif
void run() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#else
	//freopen("groups.in", "r", stdin);
#endif
}

const int N = 2e5 + 9, M = 18;
const int mod = 998244353;
ll fact[N];
ll inv[N];
ll invfact[N];
void factInverse() {
	fact[0] = inv[1] = fact[1] = invfact[0] = invfact[1] = 1;
	for (long long i = 2; i < N; i++) {
		fact[i] = (fact[i - 1] * i) % mod;
		inv[i] = mod - (inv[mod % i] * (mod / i) % mod);
		invfact[i] = (inv[i] * invfact[i - 1]) % mod;
	}
}

ll nCr(int n, int r) {
	if (r > n)
		return 0;
	return (((fact[n] * invfact[r]) % mod) * invfact[n - r]) % mod;
}

void add(ll &a, ll b) {
	if ((a += b) >= mod)
		a -= mod;
}

int n, m;
ll dp[13][5009];
int solve(int idx, int cnt) {
	if (idx < 0)
		return cnt == 0;
	cnt += ((m >> idx) & 1);
	ll &rt = dp[idx][cnt];
	if (~rt)
		return rt;
	rt = 0;
	for (int i = 0; i <= cnt; i += 2)
		add(rt, (solve(idx - 1, (cnt - i) * 2) * nCr(n, i)) % mod);
	return rt;
}
int main() {
	run();
	factInverse();
	memset(dp, -1, sizeof dp);
	cin >> n >> m;
	cout << solve(12, 0) << endl;
}

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

typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

#define fastio() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define test() int t;cin>>t;for(int test=1;test<=t;test++)
#define pb push_back
#define nl cout<<"\n"
#define F first
#define S second
#define all(x) x.begin(),x.end()

template<class C> void min_self( C &a, C b ){ a = min(a,b); }
template<class C> void max_self( C &a, C b ){ a = max(a,b); }

const ll MOD = 998244353;
ll mod( ll n, ll m=MOD ){ n%=m;if(n<0)n+=m;return n; }

const int MAXN = 5005;
const int LOGN = 21;
const ll INF = 1e14;
int dx[] = {1,0,-1,0};
int dy[] = {0,1,0,-1};

template<class T1, class T2> void add( T1 &x, T2 y, ll m = MOD )
{
    x += y;
    if( x >= m )
        x -= m;
}

template<class T1, class T2> void sub( T1 &x, T2 y, ll m = MOD )
{
    x -= y;
    if( x < 0 )
        x += m;
}


template<class T> class Math
{
public:
    vector<T>fact,invfact;
    Math( int n )
    {
        fact.resize(n);
        invfact.resize(n);
        fact[0] = invfact[0] = 1;
        for(int i=1;i<n;i++)
        {
            fact[i] = mod( i * fact[i-1] );
            invfact[i] = modinv( fact[i] );
        }
    }
    T modinv( T x, T m = MOD )
    {
        return expo(x,m-2,m);
    }
    T expo( T base, T exp, T m = MOD )
    {
        T res = 1;
        while( exp )
        {
            if( exp&1 )
                res = mod( res*base, m );
            base = mod( base*base, m );
            exp >>= 1;
        }
        return res;
    }
    T choose( T n, T k )
    {
        if( k < 0 || k > n ) return 0;
        T ans = fact[n];
        ans = mod( ans * invfact[n-k] );
        ans = mod( ans * invfact[k] );
        return ans;
    }
};

Math<ll> mat(MAXN);

ll dp[5005];

int main() 
{
    // #ifdef gupta_samarth
        // freopen("input.txt", "r", stdin);
        // freopen("output.txt", "w", stdout);
    // #endif
    fastio();

    int n,m; cin>>n>>m;

    dp[0] = 1;
    // dp[i] = no of sum 

    for(int bit=15; bit>=0; bit--)
    {
        ll now = 1LL<<bit;
        vector<int> ndp(5005,0);
        for(int sum=0; sum<=m; sum++)
        {
            for(int times=0; times<=n; times += 2)
            {
                ll adds = times*now;
                if(sum + adds <= m)
                {
                    add(ndp[sum+adds], mod(dp[sum] * mat.choose(n,times)));
                }
            }
        }
        for(int sum=0; sum<=m; sum++)
            dp[sum] = ndp[sum];
    }

    cout<<dp[m],nl;


    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}
