#include <bits/stdc++.h>
using namespace std;
const auto PI = acos(-1);
/**
* @brief Permutes an array of numbers by the inverse of its binary index.
* @tparam T The type of value contained in $a$.
* @param a A reference to a vector that is to be sorted.
* @return Nothing.
*
* Changes $a$ by the reverse of the binary representation of each index
* from $[0, \texttt{a}.size())$.
*
* For instance, let $a = [0, 1, 2, 3, 4, 5, 6, 7]$. Applying `
* reverse_bit_sort(a)` would change $a$ into $[0, 4, 2, 6, 1, 5, 3, 7]$.
*
* Note that the contents of $a$ are modified.
*/
template<typename T>
void reverse_bit_sort(vector<T> &a) {
int n = a.size();
for (int i = 1, j = 0; i < n; i++) {
// i - current index
// j - current reversed index
// t - current bit
// To transition from i to i + 1, flip
// all prefix 1s in j and the first set bit.
int t = n >> 1;
for (; t & j; t >>= 1)
j ^= t;
j ^= t;
if (i < j)
swap(a[i], a[j]);
}
}
/**
* @brief Computes the discrete fourier transform of $a$.
* @tparam T A floating point type, such that $a$ contains `std::complex<T>`.
* @param a A reference to a vector that is to have the DFT computed.
* @return Nothing.
*
* Given a polynomial $a = a[0] + a[1]x + a[2]x^2 + \dots = \sum_{i = 0}^{n - 1} a[i]x^i$,
* computes a vector $z$ such that $z[i] = a(w_n^i)$ for $i \in [0, n)$; that is, evaluates
* $a$ at each of the roots of unity for order $n$.
*
* Note that the contents of $a$ are modified.
*/
template<typename T>
typename enable_if<is_floating_point<T>::value, void>::type
fast_fourier_transform(vector<complex<T>> &a) {
int n = a.size();
// eliminate need for recursion using butterfly transform
reverse_bit_sort(a);
// iterate over length of segment
for (int l = 2; l <= n; l <<= 1) {
// l - length of segment
// theta - angle len
// dw - change in w
// i - current block
// j - current index
// w - current value
T theta = 2 * PI / l;
complex<T> dw(cos(theta), sin(theta));
for (int i = 0; i < n; i += l) {
complex<T> w = 1; // trivial root
for (int j = 0; j < l / 2; j++, w *= dw) {
auto t1 = a[i + j], t2 = a[i + j + l / 2] * w;
a[i + j] = t1 + t2, a[i + j + l / 2] = t1 - t2;
}
}
}
}
/**
* @brief Computes the inverse discrete fourier transform of $a$.
* @tparam T A floating point type, such that $a$ contains `std::complex<T>`.
* @param a A reference to a vector that is to have the inverse DFT computed.
* @return Nothing.
*
* Given a vector $a$ such that $a[i] = p(w_n^i)$ for some polynomial $p$ of
* degree $n$, computes the vector of coefficients that constitute $p$. In
* other words, it interpolates a polynomial evaluated at the roots of unity
* of order $n$.
*
* Note that the contents of $a$ are modified.
*/
template<typename T>
typename enable_if<is_floating_point<T>::value, void>::type
inverse_fast_fourier_transform(vector<complex<T>> &a) {
int n = a.size();
// eliminate need for recursion using butterfly transform
reverse_bit_sort(a);
for (int l = 2; l <= n; l <<= 1) {
// l - length of segment
// theta - angle len (note sign change)
// dw - change in w
// i - current block
// j - current index
// w - current value
T theta = -2 * PI / l;
complex<T> dw(cos(theta), sin(theta));
for (int i = 0; i < n; i += l) {
complex<T> w = 1;
for (int j = 0; j < l / 2; j++) {
auto t1 = a[i + j], t2 = a[i + j + l / 2] * w;
a[i + j] = t1 + t2;
a[i + j + l / 2] = t1 - t2;
w *= dw;
}
}
}
// divide all coefficients by $n$
// (derived from inverse of vandermonde matrix)
for (int i = 0; i < n; i++)
a[i] /= n;
}
/**
* @brief Computes the convolution of two vectors using fast fourier transform.
* @tparam T The type contained in the vectors.
* @tparam U A floating point type (defaulted to double) used in FFT.
* @param a The first vector
* @param b The second vector
* @return The convolution of $a$ and $b$.
*
* Given two vectors $a$ and $b$, computes $c$ such that
* $c[i] = \sum_{j = 0}^i a[j]b[i - j]$ for $i \in [0, n + m - 1)$.
*
* Note that this method runs in $\mathcal{O}(n\log n)$ (as opposed to the $\mathcal{O}(n^2)$
* naive solution). However, there may be issues with floating-point arithmatics and overflow.
* For best results, set `U` to `long double`.
*/
template<typename T, typename U = double>
vector<T> convolution(const vector<T> &a, const vector<T> &b) {
vector<complex<U>> pa(a.begin(), a.end()), pb(b.begin(), b.end());
// scale $n$ up to a power of two for divide and conquer to work
int n = 1;
while (n < a.size() + b.size())
n <<= 1;
pa.resize(n), pb.resize(n);
// find discrete fourier transforms of a and b
fast_fourier_transform(pa);
fast_fourier_transform(pb);
// compute point product of a and b
for (int i = 0; i < n; i++)
pa[i] *= pb[i];
// compute inverse discrete fourier transform
inverse_fast_fourier_transform(pa);
// return answer (assuming that T is a real type)
n = a.size() + b.size() - 1;
vector<T> ret(n);
for (int i = 0; i < n; i++)
ret[i] = round(pa[i].real());
return ret;
}
int main() {
int N, M;
cin >> N >> M;
vector<int> A(N + 1), B(M + 1);
for (int &a : A)
cin >> a;
for (int &b : B)
cin >> b;
auto C = convolution(A, B);
for (int c : C)
cout << c << ' ';
cout << '\n';
}