#include <iostream>
#include <string>
#include <vector>
#include <array>
#include <queue>
#include <deque>
#include <algorithm>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <functional>
#include <cassert>
#include <iomanip>
#define vll vector<ll>
#define vvvl vector<vvl>
#define vvl vector<vector<ll>>
#define VV(a, b, c, d) vector<vector<d>>(a, vector<d>(b, c))
#define VVV(a, b, c, d) vector<vvl>(a, vvl(b, vll (c, d)));
#define re(c, b) for(ll c=0;c<b;c++)
#define all(obj) (obj).begin(), (obj).end()
typedef long long int ll;
typedef long double ld;
using namespace std;

inline ll mpow(ll a, ll b, ll p = -1){
  ll ret = 1, num = a;
  while(b>0){
    if(b&1) ret = (ret*num)%p;
    num = (num*num)%p;
    b /= 2;
  }
  return ret;
}

template<ll P, ll proot>
struct NTT{
  ll g;
	vector<ll> primes;
  NTT(){};
  inline ll mpow(ll a, ll b){
    ll ret = 1, num = a;
    while(b){
      if(b&1) ret = (ret*num)%P;
      num = (num*num)%P, b >>= 1;
    }
    return ret;
  }
  ll get_mod(){return P;}
  void ntt(vector<ll>&f, bool inv){
    int n, N = f.size();
    g = mpow(proot, P/N);
  	vector<ll> angles(N);angles[0] = 1;
    for(int i=1;i<N;i++) angles[i] = (angles[i-1] * g)%P;
  	for(n=0;;n++) if(N == (1<<n)) break;
  	for (int m=0;m<N;m++) {
  		int m2 = 0;
  		for(int i=0;i<n;i++) if(m&(1<<i)) m2 |= (1<<(n-1-i));
  		if(m < m2) swap(f[m], f[m2]);
  	}

    for(int i=0;i<N;i++) f[i] %= P;
    vector<ll> power(N/2);
    power[0] = 1;
  	for(int t=1;t<N;t*=2) {
  		ll w = angles[N/(2*t)];
  		if(inv) w = angles[N - N/(2*t)];
      for(int i=1;i<t;i++) power[i] = (power[i-1] * w)%P;
  		for(int i=0;i<N;i+=2*t){
  			for (int j=0;j<t;j++){
          ll x = f[i+j], y = f[i+t+j];
  				f[i+j] = (x + y * power[j])%P;
  				f[i+t+j] = x  - (y * power[j])%P;
          if(f[i+t+j]<0) f[i+t+j] += P;
  			}
  		}
  	}
  	if(inv) {
  		ll inv = mpow(N, P-2);
  		for(int i=0;i<N;i++) f[i] = (f[i]*inv)%P;
  	}
  }
  vector<ll> conv(vector<ll> A, vector<ll> B){
    assert(A.size()==B.size());
    ll N = A.size();
    vector<ll> C(N);
    ntt(A, 0);
    ntt(B, 0);
    for(int i=0;i<N;i++) C[i] = (A[i] * B[i])%P;
    ntt(C, 1);
    return C;
  }
};

vector<ll> int32mod_conv(vector<ll> a, vector<ll> b, ll P){
  if(P==998244353) return NTT<998244353, 3>().conv(a, b);
  NTT<167772161, 3> ntt1;
  NTT<469762049, 3> ntt2;
  NTT<1224736769, 3> ntt3;
  vector<ll> A = ntt1.conv(a, b);
  vector<ll> B = ntt2.conv(a, b);
  vector<ll> C = ntt3.conv(a, b);
  ll N = A.size();
  vector<ll> ret(N);
  ll x = ntt1.get_mod();
  ll y = ntt2.get_mod();
  ll z = ntt3.get_mod();
  ll ix = mpow(x, y-2, y);
  ll ixy = mpow((x*y)%z, z-2, z);
  for(int i=0;i<N;i++){
    ll v = ((B[i] - A[i])*ix)%y;
    if(v<0) v += y;
    ll xxv = A[i]+x*v;
    v = ((C[i] - (xxv%z))*ixy)%z;
    if(v<0) v += z;
    ret[i] = ((xxv%P) + ((x*y)%P)*v)%P;
  }
  return ret;
}

template<ll P>
struct FPS: vector<ll>{
  using vector<ll>::vector;
  static ll mpow(ll x, ll y){
    ll ret = 1, num = x;
    while(y){
      if(y&1) ret = (ret * num)%P;
      num = (num * num)%P;
    }
    return ret;
  }
  FPS(vll a){
    ll n = a.size();
    this->resize(n);
    for(int i=0;i<n;i++) (*this)[i] = a[i];
  }

  FPS operator + (const FPS& r){return FPS(*this) += r;}
  FPS operator - (const FPS& r){return FPS(*this) -= r;}
  FPS operator * (const FPS& r){return FPS(*this) *= r;}
  FPS operator / (const FPS& r){return FPS(*this) /= r;}
  FPS operator + (const ll& r){return FPS(*this) += r;}
  FPS operator - (const ll& r){return FPS(*this) -= r;}
  FPS operator * (const ll& r){return FPS(*this) *= r;}
  FPS operator / (const ll& r){return FPS(*this) /= r;}

  //多項式との演算
  FPS operator += (const FPS& r){
    if(r.size() > this->size()) this->resize(r.size());
    for(int i=0;i<r.size();i++) {
      (*this)[i] += r[i];
      if((*this)[i]>P) (*this)[i] -= P;
    }
    return *this;
  }
  FPS operator -= (const FPS& r){
    if(r.size() > this->size()) this->resize(r.size());
    for(int i=0;i<r.size();i++) {
      (*this)[i] -= r[i];
      if((*this)[i]<0) (*this)[i] += P;
    }
    return *this;
  }
  FPS operator *= (FPS r){
    ll n = max(this->size(), r.size()) * 2, N = 1;
    while(N < n) N*=2;
    this->resize(N);
    r.resize(N);
    return (*this) = (int32mod_conv(*this, r, P));
  }

  // FPS operator /= (FPS r){}
  //定数との演算
  FPS operator += (const ll& r){
    if(this->empty()) this->resize(1);
    (*this)[0] += r;
    if((*this)[0]>P) (*this)[0] -= P;
    return *this;
  }
  FPS operator -= (const ll& r){
    if(this->empty()) this->resize(1);
    (*this)[0] -= r;
    if((*this)[0]<0) (*this)[0] += P;
    return *this;
  }
  FPS operator *= (const ll& r){
    if(this->empty()) this->resize(1);
    const ll n = this->size();
    for(int i=0;i<n;i++) (*this)[i] = ((*this)[i] * r)%P;
    return *this;
  }

  FPS operator /= (const ll& r){
    if(this->empty()) this->resize(1);
    ll inv = mpow(r, P-2);
    const ll n = this->size();
    for(int i=0;i<n;i++) (*this)[i] = ((*this)[i] * inv)%P;
    return *this;
  }

  FPS inv(){

  }

  FPS log(){

  }

  FPS sqrt(){

  }

  FPS exp(){

  }

  FPS pow(){

  }

};

typedef FPS<998244353> fps;
int main(){
  ll n, m;scanf("%lld %lld", &n, &m);
  vll a(n), b(m);
  for(int i=0;i<n;i++) scanf("%lld", &a[i]);
  for(int i=0;i<m;i++) scanf("%lld", &b[i]);
  fps A(a);
  fps B(b);
  A *= B;
  for(int i=0;i<n+m-2;i++) printf("%lld ", A[i]);
  printf("%lld\n", A[n+m-2]);
}


Measured memory_bytes: 86076