Problem:
Score : 800 points

Problem Statement

Find the number, modulo 998244353, of sequences of length N consisting of 0, 1 and 2 such that none of their contiguous subsequences totals to X.

Constraints

1 \leq N \leq 3000

1 \leq X \leq 2N

N and X are integers.

Input

Input is given from Standard Input in the following format:

N X

Output

Print the number, modulo 998244353, of sequences that satisfy the condition.

Sample Input 1

3 3

Sample Output 1

14

14 sequences satisfy the condition: (0,0,0),(0,0,1),(0,0,2),(0,1,0),(0,1,1),(0,2,0),(0,2,2),(1,0,0),(1,0,1),(1,1,0),(2,0,0),(2,0,2),(2,2,0) and (2,2,2).

Sample Input 2

8 6

Sample Output 2

1179

Sample Input 3

10 1

Sample Output 3

1024

Sample Input 4

9 13

Sample Output 4

18402

Sample Input 5

314 159

Sample Output 5

459765451

Solution in C++14 (GCC 5.4.1) (judge verdict: Time Limit Exceeded)

//Pantyhose(black) + glasses = infinity

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

#define debug(x) cerr << #x << " = " << x << '\n';
#define BP() cerr << "OK!\n";
#define PR(A, n) {cerr << #A << " = "; for (int64_t _=1; _<=n; ++_) cerr << A[_] << ' '; cerr << '\n';}
#define PR0(A, n) {cerr << #A << " = "; for (int64_t _=0; _<n; ++_) cerr << A[_] << ' '; cerr << '\n';}
#define FILE_NAME "data"

const int64_t MAX_N = 3002;
const int64_t ROOT = 15311432;
const int64_t ROOT_1 = 469870224;
const int64_t ROOT_PW = 1<<23;
const int64_t MOD = 998244353;

int64_t n, x, rev[MAX_N*4], inv[MAX_N*4];
int64_t pw2[MAX_N], C[MAX_N][MAX_N], f[MAX_N][MAX_N*2], g[MAX_N][MAX_N];

void read_input() {
    cin >> n >> x;
}

void NTT(vector<int64_t> &a, bool invert) {
    int64_t n = a.size();

    for (int64_t i=1; i<n; ++i) {
        if (i<rev[i])
            swap(a[i], a[rev[i]]);
    }

    for (int64_t len=2; len<=n; len <<= 1) {
        int64_t wlen = invert ? ROOT_1 : ROOT;

        for (int64_t i=len; i<ROOT_PW; i <<= 1)
            wlen = 1LL * wlen * wlen % MOD;

        for (int64_t i=0; i<n; i += len) {
            int64_t w = 1;
            for (int64_t j=0; j<len/2; ++j) {
                int64_t u = a[i+j], v = 1LL * a[i+j+len/2] * w % MOD;
                a[i+j] = (u + v < MOD ? u + v : u + v - MOD);
                a[i+j+len/2] = (u - v >=0 ? u - v : u - v + MOD);
                w = 1LL * w * wlen % MOD;
            }
        }
    }

    if (invert) {
        for (int64_t i=0; i<n; ++i)
            a[i] = 1LL * a[i] * inv[n] % MOD;
    }
}

void square(vector<int64_t> &a) {
    int64_t n = 1;
    while (n < 2*a.size())
        n <<= 1;
    a.resize(n);
    // PR0(a, a.size());

    NTT(a, false);
    // PR0(a, a.size());

    for (int64_t i=0; i<n; ++i)
        a[i] = 1LL * a[i] * a[i] % MOD;

    NTT(a, true);
}

void init() {
    int64_t tmp = 1;
    while (tmp<(n+1)*2)
        tmp <<= 1;

    inv[1] = 1;
    for (int64_t i=2; i<=tmp; ++i)
       inv[i] = MOD - 1LL * inv[MOD%i] * (MOD / i) % MOD;

    for (int64_t i=1, j=0; i<tmp; ++i) {
        int64_t bit = tmp>>1;
        for (; j & bit; bit >>= 1)
            j ^= bit;
        j ^= bit;
        rev[i] = j;
    }
    // PR0(rev, tmp);

    for (int64_t i=0; i<=n; ++i)
        C[i][0] = C[i][i] = 1;

    for (int64_t i=1; i<=n; ++i) {
        for (int64_t j=1; j<i; ++j)
            C[i][j] = (C[i-1][j] + C[i-1][j-1]) % MOD;
    }

    pw2[0] = 1;
    for (int64_t i=1; i<=n; ++i)
        pw2[i] = pw2[i-1] * 2 % MOD;

    f[0][0] = 1;

    for (int64_t l=1; l<=n; ++l) {
        for (int64_t s=0; s<=x; ++s) {
            f[l][s] = f[l-1][s];
            if (s>=1)
                f[l][s] = (f[l][s] + f[l-1][s-1]) % MOD;
            if (s>=2)
                f[l][s] = (f[l][s] + f[l-1][s-2]) % MOD;
        }
    }
    // debug(f[n][2]);
}

int64_t case1() {
    vector<int64_t> h;

    for (int64_t t=0; t<=x/2; ++t) {
        h.assign(n+1, 0);

        for (int64_t l=0; l<=n; ++l) {
            if (l<=t)
                h[l] = pw2[l];
            else
                h[l] = (1LL * h[l-1] * 2 - C[l-1][t] + MOD) % MOD;
        }

        square(h);
        // if (t==1)
        //     PR0(h, n+1);

        for (int64_t l=0; l<=n; ++l)
            g[l][t] = h[l];
    }
    // debug(g[2][1]);

    int64_t res = 0;

    for (int64_t l=0; n-l-2>=0; ++l) {
        for (int64_t s=(x+1)%2; s+2<=x; s += 2) {
            // cerr << l << ' ' << s << ' ' << f[l][s] * g[n-l-2][(x-2-s)/2] << '\n';
            res = (res + 1LL * f[l][s] * g[n-l-2][(x-2-s)/2]) % MOD;
        }
    }

    if (x%2==0)
        res = (res + g[n-1][(x-1)/2]) % MOD;
    else
        res = (res + pw2[n]) % MOD;

    return res;
}

int64_t case2() {
    int64_t res = 0;

    for (int64_t s=x%2; s<x; s += 2)
        res = (res + f[n][s]) % MOD;

    return res;
}

int main() {
	#ifdef GLASSES_GIRL
		freopen(FILE_NAME".in", "r", stdin);
		freopen(FILE_NAME".out", "w", stdout);
	#endif
	ios::sync_with_stdio(0); cin.tie(0);

	read_input();
	init();
	cout << (case1() + case2()) % MOD;
}