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>
#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &a) {
  in >> a.first >> a.second;
  return in;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &out, pair<T1, T2> a) {
  out << a.first << " " << a.second;
  return out;
}
template <typename T, typename T1>
T maxs(T &a, T1 b) {
  if (b > a) a = b;
  return a;
}
template <typename T, typename T1>
T mins(T &a, T1 b) {
  if (b < a) a = b;
  return a;
}
const int MOD = 1000000007;
struct mod_int {
  int val;
  mod_int(long long v = 0) {
    if (v < 0) v = v % MOD + MOD;
    if (v >= MOD) v %= MOD;
    val = v;
  }
  static int mod_inv(int a, int m = MOD) {
    int g = m, r = a, first = 0, second = 1;
    while (r != 0) {
      int q = g / r;
      g %= r;
      swap(g, r);
      first -= q * second;
      swap(first, second);
    }
    return first < 0 ? first + m : first;
  }
  explicit operator int() const { return val; }
  mod_int &operator+=(const mod_int &other) {
    val += other.val;
    if (val >= MOD) val -= MOD;
    return *this;
  }
  mod_int &operator-=(const mod_int &other) {
    val -= other.val;
    if (val < 0) val += MOD;
    return *this;
  }
  static unsigned fast_mod(uint64_t first, unsigned m = MOD) {
    return first % m;
    unsigned x_high = first >> 32, x_low = (unsigned)first;
    unsigned quot, rem;
    asm("divl %4\n" : "=a"(quot), "=d"(rem) : "d"(x_high), "a"(x_low), "r"(m));
    return rem;
  }
  mod_int &operator*=(const mod_int &other) {
    val = fast_mod((uint64_t)val * other.val);
    return *this;
  }
  mod_int &operator/=(const mod_int &other) { return *this *= other.inv(); }
  friend mod_int operator+(const mod_int &a, const mod_int &b) {
    return mod_int(a) += b;
  }
  friend mod_int operator-(const mod_int &a, const mod_int &b) {
    return mod_int(a) -= b;
  }
  friend mod_int operator*(const mod_int &a, const mod_int &b) {
    return mod_int(a) *= b;
  }
  friend mod_int operator/(const mod_int &a, const mod_int &b) {
    return mod_int(a) /= b;
  }
  mod_int &operator++() {
    val = val == MOD - 1 ? 0 : val + 1;
    return *this;
  }
  mod_int &operator--() {
    val = val == 0 ? MOD - 1 : val - 1;
    return *this;
  }
  mod_int operator++(int32_t) {
    mod_int before = *this;
    ++*this;
    return before;
  }
  mod_int operator--(int32_t) {
    mod_int before = *this;
    --*this;
    return before;
  }
  mod_int operator-() const { return val == 0 ? 0 : MOD - val; }
  bool operator==(const mod_int &other) const { return val == other.val; }
  bool operator!=(const mod_int &other) const { return val != other.val; }
  mod_int inv() const { return mod_inv(val); }
  mod_int pow(long long p) const {
    assert(p >= 0);
    mod_int a = *this, result = 1;
    while (p > 0) {
      if (p & 1) result *= a;
      a *= a;
      p >>= 1;
    }
    return result;
  }
  friend ostream &operator<<(ostream &stream, const mod_int &m) {
    return stream << m.val;
  }
  friend istream &operator>>(istream &stream, mod_int &m) {
    return stream >> m.val;
  }
};
int solve() {
  int n;
  cin >> n;
  vector<mod_int> a(n + 1);
  vector<mod_int> d(n + 1);
  for (int i = 1; i < n; i++) {
    cin >> a[i];
  }
  d[1] = 1;
  for (int i = 2; i <= n; i++) {
    d[i] = d[i - 1] * (a[i - 1]);
  }
  vector<mod_int> c(n + 1);
  for (int i = 1; i < n; i++) {
    c[i] = d[i + 1];
  }
  vector<mod_int> p(2 * n);
  for (int i = 1; i < n; i++) {
    for (int j = 1; j < n; j++) {
      p[i + j] += c[i] * c[j];
    }
  }
  vector<mod_int> ans(2 * n);
  for (int i = 1; i < n; i++) {
    mod_int t = (a[i] - 1) / 2;
    t *= d[i];
    t /= a[i];
    for (int j = 2; j <= 2 * n - 2; j++) {
      ans[j] += p[j] * t;
    }
    t = d[i];
    mod_int v = a[i];
    int pt = i;
    vector<mod_int> poly(n + 1);
    poly[0] = -1;
    for (int j = 1; j + i <= n; j++) {
      ans[j] += t * v;
      v *= a[++pt];
    }
    v = 1;
    for (int j = i + 1; j < n; j++) {
      v *= a[j];
      poly[j - i] = -2 * v;
    }
    v = a[i] * a[i];
    v = v.inv();
    for (int j = 2; j <= 2 * n - 2; j++) {
      p[j] *= v;
    }
    vector<mod_int> np(2 * n);
    for (int j = 2; j <= 2 * n - 2; j++) {
      np[j - 2] = p[j];
    }
    for (int j = 0; j <= n; j++) {
      np[j] += poly[j];
    }
    swap(p, np);
  }
  for (int i = 1; i <= 2 * n - 2; i++) {
    cout << ans[i] << " ";
  }
  return 0;
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int t = 1;
  while (t--) {
    solve();
  }
  return 0;
}
