// luogu-judger-enable-o2·
/*(
ntt 模板
luogu P3803
in:
n , m
0,...,a[n]
0,...,b[m]
example:
1 2
1 2
1 2 1
1 4 5 2
*/
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define int long long
void in(int &x){
x=0;char c=getchar();
long long y=1;
while(c<‘0‘||c>‘9‘){if(c==‘-‘)y=-1;c=getchar();}
while(c>=‘0‘&&c<=‘9‘){x=(x<<3)+(x<<1)+c-‘0‘;c=getchar();}
x*=y;
}
void o(int x){
if(x<0){x=-x;putchar(‘-‘);}
if(x>9)o(x/10);
putchar(x%10+‘0‘);
}
const int _ = 1e7+10;
const int mod = 998244353;//模数
const int G = 3;//原根
int ppo(int x,int p){
int t=x,res=1;
while(p>0){
if(p&1)res=(res*t)%mod;
t=(t*t)%mod;
p>>=1;
}
return res%mod;
}
int n,m;
int limit = 1 , bit;
int a[_],b[_];
int r[_];
void ntt(int *A,int type)
{
for(int i=0;i<limit;i++)if(i<r[i])swap(A[i],A[r[i]]);
for(int mid = 1;mid < limit;mid<<=1){//当前区间的一半
int wn = ppo(type==1 ? G:ppo(G,mod-2),(mod-1)*ppo(mid<<1,mod-2)%mod);
for(int R = mid << 1,j = 0;j < limit;j+=R){//回溯区间大小 最大不超过 limit
int w = 1;
for(int k = 0 ;k<mid;k++,w=w*wn%mod){
int x = A[j+k],y = w*A[j+mid+k]%mod;
A[j+k]=x+y,A[j+k]%=mod;
A[j+k+mid]=x-y+mod,A[j+k+mid]%=mod;
}
}
}
}
signed main() {
in(n);in(m);
for(int i = 0;i <= n;i++)cin>>(a[i]),a[i]=(a[i]+mod)%mod;
for(int j = 0;j <= m;j++)cin>>(b[j]),b[j]=(b[j]+mod)%mod;
while (limit<=n+m)limit<<=1,bit++;
for(int i = 0 ;i<limit;i++){
r[i]=(r[i>>1]>>1)|((i&1)<<(bit-1));//反转序列
}
ntt(a,1);
ntt(b,1);
for(int i=0;i<=limit;i++)a[i]=a[i]*b[i]%mod;//y;
ntt(a,-1);
int inv = ppo(limit,mod-2);//n 的逆元 除n运算
for(int i=0;i<=n+m;i++){
printf("%lld ",a[i]*inv%mod);
}
return 0;
}
快速数论变换ntt