#include <vector>
#include <iostream>
using namespace std;

constexpr int M = 998244353;

class ModComb {
    long long *fact, *facti;
    const int mod;
public:
    explicit ModComb(int n, int m) : mod(m) {
        fact = new long long[n+1];
        facti = new long long[n+1];
        fact[0] = 1; facti[0] = 1;
        for (int i = 1; i <= n; i++) fact[i] = (fact[i-1] * i) % m;
        // calc 1/n!
        long long &inv = facti[n], pw = fact[n];
        inv = 1;
        for (int e = mod-2; e > 0; e /= 2) {
            if (e&1) inv = inv * pw % mod;
            pw = pw * pw % mod;
        }
        for (int i = n-1; i > 0; i--) facti[i] = (facti[i+1] * (i+1)) % m;
    }

    ~ModComb() {
        if (fact) delete[] fact;
        if (facti) delete[] facti;
    }

    long long getFact(int n) const {
        return fact[n];
    }

    long long getFactInv(int n) const {
        return facti[n];
    }

    long long getComb(int n, int k) const {
        if (n < 0 || k < 0 || k > n) return 0;
        return fact[n] * facti[k] % mod * facti[n-k] % mod;
    }

    long long getPerm(int n, int k) const {
        if (n < 0 || k < 0 || k > n) return 0;
        return fact[n] * facti[n-k] % mod;
    }
};

int main() {
    int n, m; cin >> n >> m;
    ModComb mc(n+2, M);
    vector<long long> f(m+1, 0);
    f[0] = 1;
    for (int i = 2; i <= m; i += 2) {
        long long sum = 0;
        for (int k = 0; k <= min(n, i); k += 2) {
            if ((i - k) / 2 % 2 != 0) continue;
            sum += mc.getComb(n, k) * f[(i-k)/2] % M;
            // cerr << i << ' ' << k << ' ' << sum << ' ' << (i - k) / 2 << endl;
        }
        f[i] = sum % M;
        // cerr << i << ' ' << f[i] << endl;
    }
    cout << f[m] << endl;
}

    /**   Created by: Humberto Yusta
          Codeforces User: humbertoyusta
          Country: Cuba                    */
#include<bits/stdc++.h>
using namespace std;
/// Pragmas
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline","03") // Optimization flags
//#pragma GCC option("arch=native","tune=native","no-zero=upper") // Enable AVX
//#pragma GCC target("avx2") // Enable AVX
//#pragma comment(linker, "/STACK:1024000000,1024000000") // Increase stack limit
//#pragma GCC target("sse,sse2,sse,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") // I don't know what it is
/// Macros:
#define int long long
#define f first
#define s second
#define db(x) cerr << #x << ": " << (x) << '\n';
#define pb push_back
#define lb lower_bound
#define up upper_bound
#define all(x) x.begin() , x.end()
#define rall(x) x.rbegin() , x.rend()
#define enl '\n'
typedef pair<int,int> ii;
typedef long double ld;
typedef unsigned long long ull;
/// Constraints:
const int maxn = 5050;
const int mod = 998244353;
const int mod2 = 998244353;
const ld eps = 1e-9;
const int inf = ((1ll<<31ll)-1ll);
const int INF = 1ll * mod * mod;
const ld pi = acos(-1);
/// Prime Numbers:
// 2, 173, 179, 181, 197, 311, 331, 737, 1009, 2011, 2027, 3079, 4001, 10037, 10079, 20011, 20089;
// 100003, 100019, 100043, 200003, 200017, 1000003, 1000033, 1000037, 1000081;
// 2000003, 2000029, 2000039, 1000000007, 1000000021, 2000000099;
/// Functions:
#define lg2(x) 31 - __builtin_clz(x)
#define lgx(x,b) ( log(x) / log(b) )
/// Red-Black Tree Template ---------------------------------
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//typedef tree < long long ,  null_type ,  less<long long> ,  rb_tree_tag ,  tree_order_statistics_node_update > ordered_set;
/// Quick Pow------------------------------------------------
int qpow(int b,int e){
    if( !e ) return 1;
    if( e & 1 ) return qpow(b,e-1) * b % mod;
    int pwur = qpow(b,e>>1);
    return pwur * pwur % mod;
}
int modinv(int x){ return qpow(x,mod-2); }
bool isprime(int x){
    for(int i=2; i*i<=x; i++)
        if( x % i == 0 )
            return false;
    return true;
}
/// My Code -------------------------------------------------

int n, m, dp[15][maxn], C[maxn][maxn], f[maxn];

int32_t main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    cout.setf(ios::fixed); cout.precision(10);
    srand(time(NULL));

    //freopen("a.in","r",stdin);
    //freopen("a.in","w",stdout);

    C[0][0] = 1;
    for(int i=1; i<maxn; i++){
        for(int j=0; j<maxn; j++){
            C[i][j] = C[i-1][j];
            if( j ){
                C[i][j] += C[i-1][j-1];
                C[i][j] %= mod;
            }
        }
    }

    cin >> n >> m;
    for(int i=0; i<=n; i++){
        if( i % 2 ) f[i] = 0;
            else f[i] = C[n][i];
    }
    for(int i=0; i<=m; i++){
        dp[0][i] = f[i];
    }
    for(int i=1; (1<<i)<=m; i++){
        for(int j=0; j<=m; j++){
            for(int k=j; k>=0; k-=(1<<i)){
                dp[i][j] = ( dp[i][j] + dp[i-1][k] * ( f[(j-k)/(1<<i)] ) ) % mod;
            }
        }
    }

    int ans = 0;
    for(int i=0; i<14; i++)
        if( ( 1 << i ) <= m && ( 1 << ( i + 1 ) ) > m )
            ans = dp[i][m];
    cout << ans << '\n';

    return 0;
}
