#include <bits/stdc++.h>
using namespace std;
const int maxN = 3e6 + 10;
const int P = 998244353, g = 3, gi = 332748118;
int a[maxN], b[maxN], rev[maxN];
int n, m, limit, len;
void read() {
cin >> n >> m;
for (int i = 0; i <= n; i++) {
cin >> a[i];
a[i] = (a[i] + P) % P;
}
for (int i = 0; i <= m; i++) {
cin >> b[i];
b[i] = (b[i] + P) % P;
}
limit = 1;
len = 0;
while (limit <= (n + m)) {
limit <<= 1;
len++;
}
for (int i = 0; i < limit; i++)
rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (len - 1));
}
namespace NTTCore {
int qpow(int a, int b) {
int ans = 1;
while (b) {
if (b & 1)
ans = (ans * a) % P;
a = (a * a) % P;
b >>= 1;
}
return ans % P;
}
void NTT(int* A, int type) {
for (int i = 0; i < limit; i++) {
if (i < rev[i])
swap(A[i], A[rev[i]]);
}
for (int mid = 1; mid < limit; mid <<= 1) {
int gn = qpow((type == 1 ? g : gi), (P - 1) / (mid << 1));
for (int j = 0; j < limit; j += (mid << 1)) {
int g = 1;
for (int k = 0; k < mid; k++, g = (g * gn) % P) {
int x = A[j + k], y = g * A[j + k + mid] % P;
A[j + k] = (x + y) % P, A[j + k + mid] = (x - y + P) % P;
}
}
}
}
} // namespace NTTCore
void mulequal(int a[], int b[]) {
NTTCore::NTT(a, 1);
NTTCore::NTT(b, 1);
for (int i = 0; i < limit; i++) {
a[i] = (a[i] * b[i]) % P;
}
NTTCore::NTT(a, -1);
int inv = NTTCore::qpow(limit, P - 2);
for (int i = 0; i <= n + m; i++)
a[i] = (a[i] * inv) % P;
}
signed main() {
read();
mulequal(a, b);
for (int i = 0; i <= n + m; i++)
cout << a[i] << " ";
}
rt,卷出来一堆0