#include <cstdio>
#include <cmath>
#include <cassert>
#include <complex>
#include <vector>
#include <type_traits>
using namespace std;
#define FFT_LEN 65536
const double pi = acos(-1);
vector<complex<double>> fft(const vector<complex<double>> &x, const int &inv) {
static bool fft_ready = false;
static complex<double> loli[FFT_LEN];
if (!fft_ready) {
for (int k = 0; k<FFT_LEN; k++) {
loli[k] = exp(complex<double>(0, 2 * pi*k / FFT_LEN));
}
fft_ready = true;
}
int n = x.size();
assert((n&-n) == n && n <= FFT_LEN && abs(inv) == 1);
vector<complex<double>> X = x;
for (int i = 1, j = 0; i<n; i++) {
for (int k = n >> 1; !((j ^= k)&k); k >>= 1);
if (i < j) {
swap(X[i], X[j]);
}
}
for (int i = 2; i <= n; i *= 2) {
int d = (inv == 1) ? FFT_LEN - (FFT_LEN / i) : FFT_LEN / i;
for (int j = 0; j<n; j += i) {
for (int k = 0, a = 0; k<i / 2; k++, a = (a + d) % FFT_LEN) {
complex<double> s = X[j + k], t = loli[a] * X[j + k + i / 2];
X[j + k] = s + t;
X[j + k + i / 2] = s - t;
}
}
}
if (inv == -1) {
for (int i = 0; i<(int)X.size(); i++) {
X[i] /= n;
}
}
return X;
}
template<class R, class T>
class polynomial_base {
public:
polynomial_base(size_t n = 0) : a(n) {
}
polynomial_base(const std::vector<R> &coef) : a(coef) {
}
size_t size() const {
return a.size();
}
void resize(size_t n) {
a.resize(n);
}
R &operator[](int i) {
assert((0 <= i) && (i < static_cast<int>(a.size())));
return a[i];
}
const R &operator[](int i) const {
return (*const_cast<polynomial_base *>(this))[i];
}
T operator*(const polynomial_base &another) const {
if (!size() || !another.size()) {
return T();
}
T result(size() + another.size() - 1);
for (int i = 0; i<(int)size(); i++) for (int j = 0; j<(int)another.size(); j++) {
result[i + j] += a[i] * another[j];
}
return result;
}
private:
std::vector<R> a;
};
template<class R>
class polynomial : public polynomial_base<R, polynomial<R>> {
public:
polynomial(size_t n = 0) : polynomial_base<R, polynomial<R>>(n) {
}
polynomial(const std::vector<R> &coef) : polynomial_base<R, polynomial<R>>(coef) {
}
};
template<>
class polynomial<std::complex<double>> : public polynomial_base<std::complex<double>, polynomial<std::complex<double>>> {
public:
polynomial(size_t n = 0) : polynomial_base<std::complex<double>, polynomial<std::complex<double>>>(n) {
}
polynomial(const std::vector<std::complex<double>> &coef) : polynomial_base<std::complex<double>, polynomial<std::complex<double>>>(coef) {
}
polynomial<complex<double>> operator*(const polynomial<complex<double>> &another) const {
int n = size() + another.size() - 1;
if (!size() || !another.size() || n <= 32) {
return polynomial_base<std::complex<double>, polynomial<std::complex<double>>>::operator*(another);
}
for (; (n&-n) != n; n += n&-n);
vector<complex<double>> x(n), y(n);
for (int i = 0; i<(int)size(); i++) {
x[i] = (*this)[i];
}
for (int i = 0; i<(int)another.size(); i++) {
y[i] = another[i];
}
x = fft(x, 1);
y = fft(y, 1);
for (int i = 0; i<n; i++) {
x[i] *= y[i];
}
polynomial<complex<double>> result(fft(x, -1));
result.resize(this->size() + another.size() - 1);
return result;
}
};
template<class R, class T>
class polynomial_primitive : public polynomial_base<R, T> {
public:
polynomial_primitive(size_t n = 0) : polynomial_base<R, T>(n) {
}
polynomial_primitive(const std::vector<R> &coef) : polynomial_base<R, T>(coef) {
}
T operator*(const polynomial_primitive &another) const {
polynomial<complex<double>> f(this->size()), g(another.size());
for (int i = 0; i<(int)this->size(); i++) {
f[i] = (*this)[i];
}
for (int i = 0; i<(int)another.size(); i++) {
g[i] = another[i];
}
polynomial<complex<double>> h = f * g;
T result(h.size());
for (int i = 0; i<(int)h.size(); i++) {
result[i] = (R)T::round(h[i].real());
}
return result;
}
};
template<class R, class T>
class polynomial_real : public polynomial_primitive<R, T> {
public:
static double round(double x) {
return x;
}
polynomial_real(size_t n = 0) : polynomial_primitive<R, T>(n) {
}
polynomial_real(const std::vector<R> &coef) : polynomial_primitive<R, T>(coef) {
}
};
template<class R, class T>
class polynomial_integer : public polynomial_primitive<R, T> {
public:
static double round(double x) {
return floor(x + 0.5);
}
polynomial_integer(size_t n = 0) : polynomial_primitive<R, T>(n) {
}
polynomial_integer(const std::vector<R> &coef) : polynomial_primitive<R, T>(coef) {
}
};
template<>
class polynomial<double> : public polynomial_real<double, polynomial<double>> {
public:
polynomial(size_t n = 0) : polynomial_real<double, polynomial<double>>(n) {
}
polynomial(const std::vector<double> &coef) : polynomial_real<double, polynomial<double>>(coef) {
}
};
template<>
class polynomial<int> : public polynomial_integer<int, polynomial<int>> {
public:
polynomial(size_t n = 0) : polynomial_integer<int, polynomial<int>>(n) {
}
polynomial(const std::vector<int> &coef) : polynomial_integer<int, polynomial<int>>(coef) {
}
};
template<>
class polynomial<long long> : public polynomial_integer<long long, polynomial<long long>> {
public:
polynomial(size_t n = 0) : polynomial_integer<long long, polynomial<long long>>(n) {
}
polynomial(const std::vector<long long> &coef) : polynomial_integer<long long, polynomial<long long>>(coef) {
}
};
int main() {
polynomial<int> f(2), g(2);
f[1] = 1, f[0] = 1;
g[1] = 1, g[0] = -1;
polynomial<int> h = f*g;
for (int i = (int)h.size() - 1; i >= 0; i--) {
printf("%d%c", h[i], i ? ' ' : '\n');
}
return 0;
}