#include<iostream>
#include<cstdio>
#include<cstring>
#include <cstdlib>  
#include <math.h>
#include <cmath>
#include<complex>
#include<cctype>
#include<string>
#include<set>
#include<iomanip>
#include <map>
#include<algorithm>
#include <functional>
#include<vector>
#include<climits>
#include<stack>
#include<queue>
#include<bitset>
#include <deque>
#include <climits>
#include <typeinfo>
#include <utility> 
#include <numeric>
using namespace std;
using Complex = complex<double>;
using ll = long long;
template<typename T>using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
const ll inf = 1145141919810364364LL;
const double EPS = 1e-10;
double PI = acos(-1.0);
#define all(x) (x).begin(),(x).end()
#define puts(x) cout << x << endl
#define rep(i,m,n) for(ll i = m;i < n;++i)
#define pb push_back
#define fore(i,a) for(auto &i:a)
#define rrep(i,m,n) for(ll i = m;i >= n;--i)


ll mod = 998244353;
ll root = 3;
struct mint {
	ll x;
	mint(ll x = 0) :x(x%mod) {}
	mint& operator+=(const mint a) {
		if ((x += a.x) >= mod) x -= mod;
		return *this;
	}
	mint& operator-=(const mint a) {
		if ((x += mod - a.x) >= mod) x -= mod;
		return *this;
	}
	mint& operator*=(const mint a) {
		(x *= a.x) %= mod;
		return *this;
	}
	mint operator+(const mint a) const {
		mint res(*this);
		return res += a;
	}
	mint operator-(const mint a) const {
		mint res(*this);
		return res -= a;
	}
	mint operator*(const mint a) const {
		mint res(*this);
		return res *= a;
	}
};

//ntt
mint wlist[30];

mint modpow(mint a, ll n) {
	mint res = 1;
	while (n > 0) {
		if (n & 1) res = res * a;
		a = a * a;
		n >>= 1;
	}
	return res;
}

vector<mint>dft(vector<mint>A, int N) {
	//bit reverse
	int h = 0;
	for (int i = 0; (1 << i) < N; i++)h++;
	for (int i = 0; i < N; i++) {
		int j = 0;
		for (int k = 0; k < h; k++) j |= (i >> k & 1) << (h - 1 - k);
		if (i < j) swap(A[i], A[j]);
	}
	//

	//butterfly 
	int cnt = 1;
	for (int b = 1; b < N; b *= 2) {
		mint w = wlist[cnt];
		mint cur = 1;
		for (int j = 0; j < b; j++) {
			for (int k = 0; k < N; k += 2 * b) {
				mint s = A[j + k];
				mint t = A[j + k + b] * cur;
				A[j + k] = s + t;
				A[j + k + b] = s - t;
			}
			cur = w * cur;
		}
		cnt++;
	}
	//

	return A;
}
vector<mint>inv_dft(vector<mint>A, int N) {
	vector<mint>arranged = dft(A, N);
	vector<mint>swapped(N);
	for (int i = 0; i < N; i++)swapped[i] = arranged[(N - i) % N];
	vector<mint>ret(N);
	mint rev = modpow(N, mod - 2);
	for (int i = 0; i < N; i++)ret[i] = rev*swapped[i];
	return ret;
}

vector<mint>ntt(vector<mint>A, vector<mint>B) {
	//calculate Nth root
	ll P = mod;
	P--;
	int N = 1;
	int cnt = 0;
	while (P % 2 == 0) {
		N *= 2;
		cnt++;
		P /= 2;
		if (A.size() + B.size() <= N)break;
	}
	mint Nroot = modpow(root, P);
	//

	//make list of root
	mint cur = Nroot;
	for (int i = cnt; i >= 0; i--) {
		wlist[i] = cur;
		cur = cur*cur;
	}
	//

	A.resize(N);
	B.resize(N);

	A = dft(A, N);
	B = dft(B, N);

	vector<mint>F(N);
	for (int i = 0; i < N; i++)F[i] = A[i] * B[i];
	return inv_dft(F, N);
}
//nttここまで



int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int N, M;
	cin >> N >> M;
	vector<mint>A(N), B(M);
	for (int i = 0; i < N; i++)cin >> A[i].x;
	for (int i = 0; i < M; i++)cin >> B[i].x;

	vector<mint>ans = ntt(A, B);
	for (int i = 0; i < N + M - 1; i++)cout << ans[i].x << " ";
	puts("");


	return 0;
}

Measured memory_bytes: 68820