#include<bits/stdc++.h>
#define ll long long
#define db double
#define lowbit(p) (p&(-p))
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define A first
#define B second
using namespace std;
void read(int &x){
	x=0; char c=getchar(); int p=1;
	for (;c<48;c=getchar())if (c=='-')p=-1;
	for (;c>47;c=getchar())x=(x<<1)+(x<<3)+(c^48);
	x*=p;
}
void read(ll &x){
	x=0; char c=getchar(); int p=1;
	for (;c<48;c=getchar())if (c=='-')p=-1;
	for (;c>47;c=getchar())x=(x<<1)+(x<<3)+(c^48);
	x*=p;
}
void Min(int &x,int y){
	if (x>y)x=y;
}
void Max(int &x,int y){
	if (x<y)x=y;
}
void Min(ll &x,ll y){
	if (x>y)x=y;
}
void Max(ll &x,ll y){
	if (x<y)x=y;
}
/*
## 题意:
有一个有k面的骰子,骰n次,对于任意两次(x,y)没有x+y=i的情况数是多少

骰子没有区别

考虑容斥?
考虑有多少对?
状态存不下.

一定是一道数学题...?
但是容斥的能是什么东西呢...?

单独考虑i的情况
那么假设恰好用了i个特殊的数字(和其他数字加起来可以构成i)和j个随便的数字(一定要用).
那么方案数就是(i+j)^(n-i-j)
k=i+j
答案其实就是
不随便的数字的个数
	i=2			1			{1}
	i=3			2			{1,2}
	...			...			...
	i=k			k-1			{1,2...k-1}
	i=k+1		k			{1,2,3...k}
	i=k+2		k-1			{2,......k}
	i=k+3		k-2			{3.......k}
	
	1+k
	
	min(i-1,2*k-i+1)
	
那么随便的个数就是
	k-min(i-1,2*k-i+1)
	
然后由于成对...
对于奇数需要特判

先写一个复杂度较大的
void cal(int x,int y){
	for (i=0;i<=x;i++){
		for (j=0;j<=y;j++){
			res+=C(x,i)*C(y,j)*(i+j)^(n-i-j);	
		}
	}
}
for (i=2;i<=2*k;i++){
	res=0;
	tmp1=min(i-1,2*k-i+1);
	tmp2=k-tmp1;
	cal(tmp1,tmp2);
	printf("%lld\n",res);
}

然后把里面的一部分拆出来

void cal(int x,int y){
	for (i=0;i<=x;i++){
		for (j=0;j<=y;j++){
			g[i+j]=chu[i]*chu[x-i]*chu[j]*chu[y-j];	
		}
	}
	for (i=0;i<=x+y){
		res+=f[i]*g[i];
		// f[i] i^(n-i)
	}
}
for (i=2;i<=2*k;i++){
	res=0;
	tmp1=min(i-1,2*k-i+1);
	tmp2=k-tmp1;
	cal(tmp1,tmp2/2);
	res=res*jiecheng[x]*jiecheng[y];
	printf("%lld\n",res);
}
看到这个情况.
该不会是.
fft吧...
不过复杂度不大够.应该不会是吧...

发现问题最重要的一部分复杂度在这里

for (i=0;i<=x;i++){
	for (j=0;j<=y;j++){
		g[i+j]=chu[i]*chu[x-i]*chu[j]*chu[y-j];	
	}
}
有没有什么快速求的方法呢.
发现每次要么x++y-- 或者x-- y++

如果偶数需要在求一次n-1的情况,然后*2再计入答案.

换一个想法重新来?

对于一个i.
考虑加起来等于i的情况数量.
如果

突然注意到模数
说不定真的是ntt2333

把相同n个球扔进m个不同篮子
*/
#define mo 998244353
ll ksm(ll a,ll b){
	ll res=1;
	for (;b;b>>=1){
		if (b&1)res=(res*a)%mo;
		a=a*a%mo;
	}
	return res;
}
#define M 2005
#define N 4005
ll jiecheng[N],chu[N],po[N];
int n,k,tmp1,tmp2;
//ll res,f[M][M];
ll C(int n,int m){
	if (n<0||m<0||n<m)return 0;
	return jiecheng[n]*chu[m]%mo*chu[n-m]%mo;
}
void init(){
	jiecheng[0]=1;
	po[0]=1;
	int i;
	for (i=1;i<N;i++){
		jiecheng[i]=jiecheng[i-1]*i%mo;
		po[i]=(po[i-1]*2)%mo;
	}
	chu[N-1]=ksm(jiecheng[N-1],mo-2);
	for (i=N-2;i>=0;i--){
		chu[i]=chu[i+1]*(i+1)%mo;
	}/*
	for (i=0;i<M;i++){
		for (j=1;j<M;j++){
			f[i][j]=C(i+j-1,j-1);
		}
	}	*/
}/*
void cal(int sum){
//	printf("---- %d ---\n",sum);
	tmp1=min(sum-1,2*k-sum+1);
	tmp2=k-tmp1;
//	printf("tmp1=%d tmp2=%d\n",tmp1,tmp2);
	res=0;
	tmp1=(tmp1+1)/2;
	int i;
	ll tmp;
	for (i=0;i*2<=n;i++){
		tmp=f[i][tmp1]*f[n-2*i][k]%mo;
		printf("%d %d %lld\n",i,tmp1,f[i][tmp1]);
		printf("%d %d %lld\n",n-2*i,k,f[n-2*i][k]);
//		printf("i=%d %lld\n",i,tmp);
		if (i&1)res=(res-tmp)%mo;
		else res=(res+tmp)%mo;
	}
	res=(res%mo+mo)%mo;
	printf("%lld\n",res);
}*/

ll cal(int sum,int n,int k){
//	printf("---- cal %d %d %d ----\n",sum,n,k);
	ll res=0;
    int tot=max(0,sum/2-max(0,sum-1-k));
    for(int i=0;i<=tot;i++){
        res=(res+po[i]*C(tot,i)%mo*C(n+k-2*tot-1,k-tot*2+i-1)%mo)%mo;
//    	printf("%d %lld\n",i,po[i]*C(tot,i)%mo*C(n+k-2*tot-1,k-tot*2+i-1)%mo);
    }
    return res;
}
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
//	freopen("1.in","r",stdin);
	int i;
	ll res;
	init();
	read(k); read(n);
	for (i=2;i<=2*k;i++){
		if (i&1)res=cal(i,n,k);
		else res=(cal(i-1,n,k-1)+cal(i-1,n-1,k-1))%mo;
		printf("%lld\n",res);
	}
	return 0;
}

Measured memory_bytes: 384