#include <bits/stdc++.h>

using namespace std;

int p;

vector<int> inv;

struct Poly {
    deque<int> cs;
    // corresponds to the polynomial cs[0]*x^0 + cs[1]*x^1 + ...
    Poly() {}
    Poly(int k) {
        if (k > 0) {
            cs.push_back(k);
        }
    }
    Poly(deque<int> cs): cs(cs) {}
    Poly shift(int k) const { // multiplies with x^k
        Poly poly(cs);
        for (int i = 0; i < k; ++i) {
            poly.cs.push_front(0);
        }
        return poly;
    }
    Poly multiply(int k) const { // multiplies with constant k
        Poly poly(cs);
        for (int& c : poly.cs) {
            c = ((c * k) % p + p) % p;
        }
        return poly;
    }
    Poly add(const Poly& o) const {
        Poly poly(cs);
        for (int i = 0; i < (int)cs.size(); ++i) {
            poly.cs[i] = ((poly.cs[i] + o.cs[i]) % p + p) % p;
        }
        if (o.cs.size() > cs.size()) {
            for (int i = (int)cs.size(); i < (int)o.cs.size(); ++i) {
                poly.cs.push_back(o.cs[i]);
            }
        }
        while (poly.cs.size() > 0 && poly.cs.back() == 0) {
            poly.cs.pop_back();
        }
        return poly;
    }
    Poly minus(const Poly& o) const {
        return add(o.multiply(-1));
    }
    void add_root(int r) {
        cs.push_front(0);
        for (int i = 0; i+1 < (int)cs.size(); ++i) {
            cs[i] = ((cs[i] - r * cs[i+1]) % p + p) % p;
        }
    };
    Poly multiply(Poly o) const {
        Poly poly(0);
        int d0 = (int)cs.size()-1, d1 = (int)o.cs.size()-1;
        int d = d0 + d1;
        for (int i = 0; i <= d; ++i) {
            int coeff = 0;
            poly.cs.push_back(0);
        }
        for (int j = 0; j <= d0; ++j) {
            for(int k = 0; k <= d1; ++k) {
                poly.cs[j+k] = (poly.cs[j+k] + cs[j] * o.cs[k]) % p;
            }
        }
        return poly;
    }
};

/*
Problem:
Given a(x), b(x) with gcd(a, b) = 1 then find r(x), s(x) such that
r(x) * a(x) + s(x) * b(x) = 1

Now let a'(x) = a(x) - b(x) * p(x)
Find r', s' recursively s.t.:
r' * a' + s' * b = 1

Then:
r' * (a - b*p) + s' * b = 1
so

r' * a + (s' - r'*p) * b = 1
and we output (r', s'-r'*p)
*/
pair<Poly, Poly> gcd(const Poly& a, const Poly& b) {
    if (a.cs.size() < b.cs.size()) {
        auto g = gcd(b, a);
        return make_pair(g.second, g.first);
    }
    if (b.cs.size() == 0) {
        assert(a.cs.size() == 1);
        return make_pair(Poly(inv[a.cs.back()]), Poly(0));
    }
    int shift = a.cs.size() - b.cs.size();
    int mult = (a.cs.back() * inv[b.cs.back()]) % p;
    // so we let a' = a - x^shift * mult * b
    Poly a_0 = a.minus(b.multiply(mult).shift(shift));
    auto g = gcd(a_0, b);
    return make_pair(g.first, g.second.minus(g.first.multiply(mult).shift(shift)));
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> p;
    inv = vector<int>(p, 0);
    for (int i = 1; i < p; ++i) {
        for (int j = 1; j < p; ++j) {
            if ((i*j) % p == 1) {
                inv[i] = j;
            }
        }
    }
    Poly p_0(1), p_1(1);
    for (int i = 0; i < p; ++i) {
        int a;
        cin >> a;
        if (a == 0) {
            p_0.add_root(i);
        } else {
            p_1.add_root(i);
        }
    }
    Poly result = gcd(p_0, p_1).first.multiply(p_0);
    while (result.cs.size() < p) {
        result.cs.push_back(0);
    }
    for (int c : result.cs) {
        cout << c << " ";
    }
    cout << endl;
    return 0;
}


Measured memory_bytes: 22528