Problem:
Score : 700 points

Problem Statement

Takahashi throws N dice, each having K sides with all integers from 1 to K. The dice are NOT pairwise distinguishable.
For each i=2,3,...,2K, find the following value modulo 998244353:

The number of combinations of N sides shown by the dice such that the sum of no two different sides is i.

Note that the dice are NOT distinguishable, that is, two combinations are considered different when there exists an integer k such that the number of dice showing k is different in those two.

Constraints

1 \leq K \leq 2000

2 \leq N \leq 2000

K and N are integers.

Input

Input is given from Standard Input in the following format:

K N

Output

Print 2K-1 integers. The t-th of them (1\leq t\leq 2K-1) should be the answer for i=t+1.

Sample Input 1

3 3

Sample Output 1

7
7
4
7
7

For i=2, the combinations (1,2,2),(1,2,3),(1,3,3),(2,2,2),(2,2,3),(2,3,3),(3,3,3) satisfy the condition, so the answer is 7.

For i=3, the combinations (1,1,1),(1,1,3),(1,3,3),(2,2,2),(2,2,3),(2,3,3),(3,3,3) satisfy the condition, so the answer is 7.

For i=4, the combinations (1,1,1),(1,1,2),(2,3,3),(3,3,3) satisfy the condition, so the answer is 4.

Sample Input 2

4 5

Sample Output 2

36
36
20
20
20
36
36

Sample Input 3

6 1000

Sample Output 3

149393349
149393349
668669001
668669001
4000002
4000002
4000002
668669001
668669001
149393349
149393349

Solution in Rust (1.15.1) (judge verdict: Accepted)

#[allow(unused_macros)]
macro_rules! parse_line {
    ( $t:ty ) => (
        {
            let mut line = String::new();
            ::std::io::stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            iter.next().unwrap().parse::<$t>().unwrap()
        }
    );

    ( $( $t:ty), +) => (
        {
            let mut line = String::new();
            ::std::io::stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            ( $(iter.next().unwrap().parse::<$t>().unwrap()),* )
        }
    );
}

#[allow(unused_macros)]
macro_rules! read_line {
    () => (
        {
            let mut line = String::new();
            ::std::io::stdin().read_line(&mut line).unwrap();
            line.pop();
            line
        }
    )
}

#[allow(unused_macros)]
macro_rules! parse_vec {
    ( $t:ty ) => (
        {
            let mut line = String::new();
            ::std::io::stdin().read_line(&mut line).unwrap();
            let iter = line.split_whitespace();
            iter.map(|v| v.parse::<$t>().unwrap()).collect::<Vec<_>>()
        }
    )
}

const FACT_MAX: usize = 300000;
const MOD: i64 = 998244353;

#[allow(dead_code)]
fn pow_mod(base: i64, power: i64, modulo: i64) -> i64 {
    let mut base = base;
    let mut power = power;
    let mut ans = 1;
    while power > 0 {
        if power & 1 == 1 {
            ans = ans * base % modulo;
        }
        power >>= 1;
        base = base * base % modulo;
    }
    ans
}

thread_local! {
    #[allow(unused)]
    pub static FACT: Vec<i64> = {
        let mut fac: Vec<i64> = vec![1; FACT_MAX+1];

        for i in 1..FACT_MAX+1 {
            fac[i] = (fac[i-1] * i as i64) as i64 % MOD;
        }
        fac
    };

    #[allow(unused)]
    pub static RFACT: Vec<i64> = {
        let mut rfac = vec![1; FACT_MAX+1];
        rfac[FACT_MAX] = FACT.with(|fact| {
            pow_mod(fact[FACT_MAX], MOD-2, MOD)
        });

        for i in (0..FACT_MAX).rev() {
            rfac[i] = (rfac[i+1] * (i+1) as i64) % MOD;
        }
        rfac
    }
}

#[allow(dead_code)]
fn combi(n: usize, m: usize) -> i64 {
    if n < m {
        return 0;
    }

    FACT.with(|fact| {
        RFACT.with( |rfact| {
            fact[n] * rfact[n-m] % MOD * rfact[m] % MOD
        })
    })
}

fn solve_odd(i: usize, k: usize, n: usize) -> i64 {
    // a + b = i (a <= b) なる組み合わせ数 p
    // pの(a,b)組のうち選ばない個数qとすると選ばれる m = p-q
    // m個の組の内一方の選び方は pCm * 2^m
    // 残りn-mを選ぶさい既に選ばれたm個の中から再度選んでも問題ない
    // したがって m と (a,b)組に含まれない k - 2p個の数(k-2p+m)から
    // n-mを重複して選ぶと k-2p+m H n-m
    // よって pCm * 2^m * k-2p+m H n-m が答えとなる

    let p = {
        let mut p=0;
        for j in 1..k+1 {
            if i-j > k { continue }
            if j >= i-j { break }
            p += 1;
        }
        p
    };

    let mut ans = 0 as i64;

    for m in 0..p+1 {
        ans += ((combi(p, m) * pow_mod(2, m as i64, MOD) % MOD) *
                combi(k-2*p+n-1, n-m)) % MOD;
        ans %= MOD;
    }

    ans
}

fn solve_even(i: usize, k: usize, n: usize) -> i64 {
    let p = {
        let mut p=0;
        for j in 1..k+1 {
            if i-j > k { continue }
            if j >= i-j { break } // k/2は含めない
            p += 1;
        }
        p
    };

    let mut ans = 0;

    for m in 0..p+1 {
        // k/2を0個含む場合
        ans += ((combi(p, m) * pow_mod(2, m as i64, MOD) % MOD) *
                combi(k-2*p+n-2, n-m)) % MOD;
        ans %= MOD;

        // k/2を1個含む場合
        ans += ((combi(p, m) * pow_mod(2, m as i64, MOD) % MOD) *
                combi(k-2*p+n-3, n-m-1)) % MOD;
        ans %= MOD;

    }

    ans
}

fn solve(k: usize, n: usize) -> Vec<i64> {
    let mut v = Vec::new();

    for i in 2..(2*k+1) {
        v.push(if i % 2 == 1 {
            solve_odd(i, k, n)
        } else {
            solve_even(i, k, n)
        });
    }

    v
}

fn main() {
    let (k, n) = parse_line!(usize, usize);

    for a in solve(k, n) {
        println!("{}", a);
    }
}

#[test]
fn solve_test() {
    assert_eq!(solve(3,3), vec![7,7,4,7,7]);
    assert_eq!(solve(4,5), vec![36,36,20,20,20,36,36]);
    assert_eq!(solve(6, 1000), vec![149393349,149393349,668669001,668669001,4000002,
                                    4000002,4000002,668669001,668669001,149393349,149393349]);
}