Problem: You are given a rooted tree. Let's denote d(x) as depth of node x: depth of the root is 1, depth of any other node x is d(y) + 1, where y is a parent of x.

The tree has the following property: every node x with d(x) = i has exactly ai children. Maximum possible depth of a node is n, and an = 0.

We define fk as the number of unordered pairs of vertices in the tree such that the number of edges on the simple path between them is equal to k.

Calculate fk modulo 109 + 7 for every 1 ≤ k ≤ 2n - 2.

Input

The first line of input contains an integer n (2 ≤ n ≤ 5 000) — the maximum depth of a node.

The second line of input contains n - 1 integers a1, a2, ..., an - 1 (2 ≤ ai ≤ 109), where ai is the number of children of every node x such that d(x) = i. Since an = 0, it is not given in the input.

Output

Print 2n - 2 numbers. The k-th of these numbers must be equal to fk modulo 109 + 7.

Examples

Input

4
2 2 2


Output

14 19 20 20 16 16 

Input

3
2 3


Output

8 13 6 9 

Note

This the tree from the first sample: 

<image>

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
template <class T, class T2>
inline void chkmax(T &x, const T2 &y) {
  if (x < y) x = y;
}
template <class T, class T2>
inline void chkmin(T &x, const T2 &y) {
  if (x > y) x = y;
}
const double PI = acos(-1);
const int MAXN = (1 << 19);
const int mod = (int)1e9 + 7;
const int inv2 = (mod + 1) / 2;
inline void addmod(int &x, int y, int mod) { (x += y) >= mod && (x -= mod); }
inline int mulmod(int x, int y, int mod) { return x * 1ll * y % mod; }
struct complex_base {
  double x, y;
  complex_base(double _x = 0, double _y = 0) {
    x = _x;
    y = _y;
  }
  friend complex_base operator-(const complex_base &a, const complex_base &b) {
    return complex_base(a.x - b.x, a.y - b.y);
  }
  friend complex_base operator+(const complex_base &a, const complex_base &b) {
    return complex_base(a.x + b.x, a.y + b.y);
  }
  friend complex_base operator*(const complex_base &a, const complex_base &b) {
    return complex_base(a.x * b.x - a.y * b.y, a.y * b.x + b.y * a.x);
  }
  friend void operator/=(complex_base &a, const double &P) {
    a.x /= P;
    a.y /= P;
  }
};
int bit_rev[MAXN];
void fft(complex_base *a, int lg) {
  int n = (1 << lg);
  for (int i = 1; i < n; i++) {
    bit_rev[i] = (bit_rev[i >> 1] >> 1) | ((i & 1) << (lg - 1));
    if (bit_rev[i] < i) swap(a[i], a[bit_rev[i]]);
  }
  for (int len = 2; len <= n; len <<= 1) {
    double ang = 2 * PI / len;
    complex_base w(1, 0), wn(cos(ang), sin(ang));
    for (int j = 0; j < (len >> 1); j++, w = w * wn)
      for (int i = 0; i < n; i += len) {
        complex_base u = a[i + j], v = w * a[i + j + (len >> 1)];
        a[i + j] = u + v;
        a[i + j + (len >> 1)] = u - v;
      }
  }
}
void inv_fft(complex_base *a, int lg) {
  int n = (1 << lg);
  for (int i = 1; i < n; i++) {
    bit_rev[i] = (bit_rev[i >> 1] >> 1) | ((i & 1) << (lg - 1));
    if (bit_rev[i] < i) swap(a[i], a[bit_rev[i]]);
  }
  for (int len = 2; len <= n; len <<= 1) {
    double ang = -2 * PI / len;
    complex_base w(1, 0), wn(cos(ang), sin(ang));
    for (int j = 0; j < (len >> 1); j++, w = w * wn)
      for (int i = 0; i < n; i += len) {
        complex_base u = a[i + j], v = w * a[i + j + (len >> 1)];
        a[i + j] = u + v;
        a[i + j + (len >> 1)] = u - v;
      }
  }
  for (int i = 0; i < n; i++) a[i] /= n;
}
complex_base A[MAXN], B[MAXN];
vector<int> mult(const vector<int> &a, const vector<int> &b) {
  vector<int> ans(a.size() + b.size(), 0);
  for (int i = 0; i < (int)a.size(); i++)
    for (int j = 0; j < (int)b.size(); j++)
      ans[i + j] = (ans[i + j] + a[i] * 1ll * b[j]) % mod;
  return ans;
  int lg = 0;
  while ((1 << lg) < (int)(a.size() + b.size())) ++lg;
  for (int i = 0; i < (1 << lg); i++) A[i] = B[i] = complex_base(0, 0);
  for (int i = 0; i < (int)a.size(); i++) A[i] = complex_base(a[i], 0);
  fft(A, lg);
  for (int i = 0; i < (1 << lg); i++) A[i] = A[i] * A[i];
  inv_fft(A, lg);
}
vector<int> mult_mod(const vector<int> &a, const vector<int> &b) {
  int base = (int)sqrtl(mod);
  vector<int> a0(a.size()), a1(a.size());
  for (int i = 0; i < (int)a.size(); i++) {
    a0[i] = a[i] % base;
    a1[i] = a[i] / base;
  }
  vector<int> b0(b.size()), b1(b.size());
  for (int i = 0; i < (int)b.size(); i++) {
    b0[i] = b[i] % base;
    b1[i] = b[i] / base;
  }
  vector<int> a01 = a0;
  for (int i = 0; i < (int)a.size(); i++) addmod(a01[i], a1[i], mod);
  vector<int> b01 = b0;
  for (int i = 0; i < (int)b.size(); i++) addmod(b01[i], b1[i], mod);
  vector<int> C = mult(a01, b01);
  vector<int> a0b0 = mult(a0, b0);
  vector<int> a1b1 = mult(a1, b1);
  vector<int> mid = C;
  for (int i = 0; i < (int)mid.size(); i++) {
    addmod(mid[i], -a0b0[i] + mod, mod);
    addmod(mid[i], -a1b1[i] + mod, mod);
  }
  vector<int> res = a0b0;
  for (int i = 0; i < (int)res.size(); i++)
    addmod(res[i], mulmod(base, mid[i], mod), mod);
  base = mulmod(base, base, mod);
  for (int i = 0; i < (int)res.size(); i++)
    addmod(res[i], mulmod(base, a1b1[i], mod), mod);
  return res;
}
int n;
int cnt[MAXN];
vector<int> answer;
void read() {
  cin >> n;
  for (int i = 1; i <= n - 1; i++) cin >> cnt[i];
  answer.assign(2 * n - 1, 0);
}
int pw(int x, int p) {
  int ret = 1;
  while (p) {
    if (p & 1) ret = (ret * 1ll * x) % mod;
    x = (x * 1ll * x) % mod;
    p >>= 1;
  }
  return ret;
}
vector<int> poly, rp;
void solve(int d, int mult) {
  if (d == n) return;
  int C = (cnt[d] * 1ll * (cnt[d] - 1)) % mod;
  C = (C * 1ll * inv2) % mod;
  int m = 1;
  for (int p = d + 1; p <= n; p++) {
    answer[p - d] =
        (answer[p - d] + (cnt[d] * 1ll * ((m * 1ll * mult) % mod)) % mod) % mod;
    m = (m * 1ll * cnt[p]) % mod;
  }
  for (int i = 1; i <= min((int)poly.size() - 1, 2 * n - 2); i++)
    answer[i] =
        (answer[i] + (C * 1ll * ((poly[i] * 1ll * mult) % mod)) % mod) % mod;
  for (int i = 2; i < (int)rp.size(); i++) {
    poly[i + 1] = (poly[i + 1] + mod - (rp[i] * 1ll * rp[1]) % mod) % mod;
    poly[i + 1] = (poly[i + 1] + mod - (rp[i] * 1ll * rp[1]) % mod) % mod;
  }
  int cc = pw(cnt[d + 1], mod - 2);
  poly.erase(poly.begin() + 1, poly.begin() + 3);
  rp.erase(rp.begin() + 1, rp.begin() + 2);
  for (auto &it : poly) it = (((it * 1ll * cc) % mod) * 1ll * cc) % mod;
  for (auto &it : rp) it = (it * 1ll * cc) % mod;
  solve(d + 1, (mult * 1ll * cnt[d]) % mod);
}
void solve() {
  poly.assign(n, 0);
  int d = 1, m = 1;
  for (int p = d + 1; p <= n; p++) {
    poly[p - d] += m;
    m = (m * 1ll * cnt[p]) % mod;
  }
  rp = poly;
  poly = mult_mod(poly, poly);
  solve(1, 1);
  for (int i = 1; i <= 2 * n - 2; i++) cout << answer[i] << " ";
  cout << '\n';
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  read();
  solve();
  return 0;
}