#include <bits/stdc++.h>

using namespace std;

using int64 = long long;

constexpr int64 P = 998244353;
constexpr int64 PRIMITIVE_ROOT = 3;

struct FiniteField {
 private:
  int64 x;
 public:
  FiniteField(int64 raw_x) : x(raw_x) {
    if (x >= P || x < 0) {
    x %= P;
    if (x < 0) x += P;
  }
}
  FiniteField() : x(0) {}
  int64 Value() const { return x; }
  inline FiniteField operator+(FiniteField o) const {
    FiniteField r(*this); r += o; return r;
  }
  inline FiniteField operator-(FiniteField o) const {
    FiniteField r(*this); r -= o; return r;
  }
  inline FiniteField operator* (FiniteField o) const {
    FiniteField r(*this); r *= o; return r;
  }
  inline FiniteField operator/ (FiniteField o) const {
    FiniteField r(*this); r /= o; return r;
  }
  inline void operator+= (FiniteField o) { x = (x + o.x) % P; }
  inline void operator-= (FiniteField o) { x = (x + P - o.x) % P; }
  inline void operator*= (FiniteField o) { x = (x * o.x) % P; }
  void operator/=(FiniteField o) {
    int64 p = P - 2; while (p) { if (p % 2) { *this *= o; } o *= o; p /= 2; }
  }
};
ostream& operator<<(ostream& s, const FiniteField& x) { s << x.Value(); return s; }

FiniteField Power(FiniteField x, int p) {
  if (p < 0) return FiniteField(1) / Power(x, -p);
  FiniteField value = 1;
  while (p) {
    if (p % 2) value *= x;
    x *= x;
    p /= 2;
  }
  return value;
}

// Verified: https://judge.yosupo.jp/problem/convolution_mod
vector<FiniteField> DMT(const vector<FiniteField>& p, int n, int sign = 1) {
  if ((P - 1) % n != 0) {
    exit(1);
  }
  FiniteField root = Power(FiniteField(PRIMITIVE_ROOT), (P - 1) / n * sign);

  int unit = 1;
  vector<FiniteField> q = p;
  FiniteField u = root;
  for (int m = n; m >= 2; m >>= 1) {
    int mh = m >> 1;
    FiniteField w = 1;
    for (int i = 0; i < mh; i++) {
      for (int j = i; j < n; j += m) {
        int k = j + mh;
        FiniteField x = q[j] - q[k];
        q[j] += q[k];
        q[k] = w * x;
      }
      w *= u;
    }
    u = u * u;
  }
  int i = 0;
  for (int j = 1; j < n - 1; j++) {
    for (int k = n >> 1; k > (i ^= k); k >>= 1);
    if (j < i) swap(q[i], q[j]);
  }
  return q;
}

vector<FiniteField> InvDMT(const vector<FiniteField>& p, int n) {
  auto q = DMT(p, n, -1);
  FiniteField d = FiniteField(1) / FiniteField(n);
  for(int i = 0; i < n; i++) {
    q[i] *= d;
  }
  return q;
}

vector<FiniteField> MultiplyFMT(
    const vector<FiniteField>& p1, const vector<FiniteField>& p2) {
  int d = p1.size() + p2.size() - 1;
  int n = 1;
  while(n < d + 1) n *= 2;
 
  auto q1 = p1;
  q1.resize(n);
  auto q2 = p2;
  q2.resize(n);
  auto r1 = DMT(q1, n);
  auto r2 = DMT(q2, n);
 
  vector<FiniteField> s(n);
  for(int i = 0; i < n; i++) {
    s[i] = r1[i] * r2[i];
  }
  return InvDMT(s, n);
}

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

  int n;
  int m;
  cin >> n >> m;
  vector<FiniteField> xs(n);
  vector<FiniteField> ys(m);
  for (int i = 0; i < n; i++) {
    int64 x;
    cin >> x;
    xs[i] = x;
  }
  for (int i = 0; i < m; i++) {
    int64 y;
    cin >> y;
    ys[i] = y;
  }

  auto zs = MultiplyFMT(xs, ys);
  for (int i = 0; i < n + m - 1; i++) {
    cout << zs[i] << " ";
  }
  cout << endl;
}


Measured memory_bytes: 64532