/* 解説にあった方法を試す
 * 動画まで見てやっと理解した
 *
 * aがすべて0の時、bもすべて0
 * f(x) = 0
 *
 * aが特定のiで1の時
 * f'(x) = f(x) + 特定のiで1
 *       = f(x) + (1 - (x - i))**(p-1)
 * 
 * これをすべてのa=1で行うと、以下の式を得る
 * (これが、解説PDFの「この値を aj = 1 であるようなすべての j に対して足し合わせれば所望の多項式が得られます。」の意味)
 * f'(x) = f(x) + (1 - (x - i1))**(p-1) + (1 - (x - i2))**(p-1) ...
 *
 * xは任意のp-1未満の整数なので、2項展開しやすいよう1とおく
 */

#include <iostream>
#include <unordered_map>
#include <vector>
#include <queue>
#include <algorithm>
#include <cmath>
#include <functional>
#include <iterator>

using namespace std;

// mod計算クラス
template <class T>
struct calc_mod {
  T n;
  T mod;

  calc_mod(T n, T mod) {
    this->n = n;
    this->mod = mod;
  }

  T plus(const T& a, const T& b) const { return (a + b) % mod; }
  calc_mod<T> operator+(const calc_mod<T>& other) const { return plus(this->n, other.n); }
  calc_mod<T> operator+(const T& other) const { return calc_mod<T>(plus(this->n, other)); }
  void operator+=(const calc_mod<T>& other) { this->n = plus(this->n, other.n); }
  void operator+=(const T& other) { this->n = plus(this->n, other); }

  T sub(const T& a, const T& b) const { return (a - b + mod) % mod; }
  calc_mod<T> operator-(const calc_mod<T>& other) const { return calc_mod<T>(sub(this->n, other.n), mod); }
  calc_mod<T> operator-(const T& other) const { return calc_mod<T>(sub(this->n, other), mod); }
  void operator-=(const calc_mod<T>& other) { this->n = sub(this->n, other.n); }
  void operator-=(const T& other) { this->n = sub(this->n, other); }

  T multi(const T& a, const T& b) const { return (a * b) % mod; }
  calc_mod<T> operator*(const calc_mod<T>& other) const { return calc_mod<T>(multi(this->n, other.n), mod); }
  calc_mod<T> operator*(const T& other) const { return calc_mod<T>(multi(this->n, other), mod); }
  void operator*=(const calc_mod<T>& other) { this->n = multi(this->n, other.n); }
  void operator*=(const T& other) { this->n = multi(this->n, other); }

  T div(const T& a, const T& b) const { return a / b; }
  calc_mod<T> operator/(const calc_mod<T>& other) const { return calc_mod<T>(div(this->n, other.n), mod); }
  calc_mod<T> operator/(const T& other) const { return calc_mod<T>(div(this->n, other), mod); }
  void operator/=(const calc_mod<T>& other) { this->n = div(this->n, other.n); }
  void operator/=(const T& other) { this->n = div(this->n, other); }

  T modu(const T& a, const T& b) const { return a % b; }
  calc_mod<T> operator%(const calc_mod<T>& other) const { return calc_mod<T>(modu(this->n, other.n), mod); }
  calc_mod<T> operator%(const T& other) const { return calc_mod<T>(modu(this->n, other), mod); }
  void operator%=(const calc_mod<T>& other) { this->n = modu(this->n, other.n); }
  void operator%=(const T& other) { this->n = modu(this->n, other); }

  //TODO: このあたり、haskellのeqみたいに定義できないか？
  bool operator==(const calc_mod<T>& other) const { return this->n == other.n; }
  bool operator==(const T& other) const { return this->n == other; }
  bool operator!=(const calc_mod<T>& other) const { return this->n != other.n; }
  bool operator!=(const T& other) const { return this->n != other; }

  bool operator>(const calc_mod<T>& other) const { return this->n > other.n; }
  bool operator>(const T& other) const { return this->n > other; }
  bool operator>=(const calc_mod<T>& other) const { return this->n >= other.n; }
  bool operator>=(const T& other) const { return this->n >= other; }
  bool operator<(const calc_mod<T>& other) const { return this->n < other.n; }
  bool operator<(const T& other) const { return this->n < other; }
  bool operator<=(const calc_mod<T>& other) const { return this->n <= other.n; }
  bool operator<=(const T& other) const { return this->n <= other; }

  calc_mod<T> pow(calc_mod<T> other) {
    return this->pow(other.n);
  }
  calc_mod<T> pow(T other) {
    // 累乗は繰り返し自乗法で
    calc_mod<T> result(1, this->mod);
    calc_mod<T> x = *this;
    T b = other;

    for (;b > 0;b /= 2) {
      if (b%2 == 1) {
        result *= x;
      }

      x *= x;
    }

    return result;
  }
};
template <class T>
string to_string(calc_mod<T> data) { //標準の数値型のように、to_stringで呼べるように
  return to_string(data.n);
}
template <class T>
ostream& operator<<(ostream& stream, calc_mod<T> data) { // cout<<でも呼べるように
  stream << to_string(data);
  return stream;
}

using modtype = calc_mod<int>;

// 余りを出さない、modの割り算
modtype div2(modtype a, modtype b) {
  auto aa = a.n;
  auto bb = b.n;

  // ここも解説から
  // a/b = a * (1/b)
  // 1/bはbの逆数。
  // p-1乗が1なので、
  // あとp掛けると1になる、p-2 乗が逆数
  return a * b.pow(b.mod-2);
}

template <class T>
string join(const vector<T>& data) {
  string result = "";
  bool is_first = true;

  for (const auto x : data) {
    if (is_first) {
      is_first = false;
    } else {
      result += " ";
    }
    result += to_string(x); //TODO: エラーにならない…
  }

  return result;
}

// Cのキャッシュ
vector<modtype> combs;
void calc_combs(int p) {
  modtype value(1, p);
  for (int i = 0; i < p; i++) {
    combs.push_back(value);
    value = div2(value * (p-1-i), modtype(i+1, p));
  }
}

int main() {

  int p;
  cin >> p;

  calc_combs(p);

  vector<modtype> bs(p, modtype(0, p));

  int a;
  for (int i = 0; i < p; i++) {
    cin >> a;

    if (a == 1) {
      bs[0] += 1; // j==0のみ、1-... の最初の候 1 を足す

      modtype pow_i = modtype(1,p);
      for (int j = p - 1; j >= 0; j--) {
        // bs[j] -= comb(p-1, j) * modtype(-i,p).pow(p-1-j); // 2項展開したx**jに当たる項。- p-1Cj * (-i)**(p-1-j)
        bs[j] -= combs[j] * pow_i;
        pow_i = pow_i * (-i);
      }
    }
  }

  /*
  for (int i = 0; i < p; i++) {
    cout << "i" << i << " comb " << combs[i] << endl;
  }
  */

  cout << join(bs) << endl;

  return 0;
}


Measured memory_bytes: 384