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 JAVA):

Solution:
import java.io.*;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.flush();out.close();
    }
        static class TaskE {
          long mod=(long)(1E9)+7;
          long rpe(long a){long b=mod-2;
           long ans=1;
           while(b!=0){
            if(b%2!=0)ans=(ans*a)%mod;
            b/=2;a=a*a%mod;
           }return ans;
          }
          long i2=rpe(2);
          long f(long c){
           return c*(c-1+mod)%mod*i2%mod;
          }
          public void solve(int testNumber, InputReader in, PrintWriter out) {
           int n=in.nextInt();
           long a[]=new long[n+10];for(int i=1;i<=n-1;i++)a[i]=in.nextLong();a[0]=1;
           long c=1;long ans[]=new long[2*n-1];
           long dp[][]=new long[2][2*n-1];int t=0;
           long v[][]=new long[n+10][n+10];
           for(int i=1;i<=n-1;i++){
            v[i][i]=(a[i]-1+mod)%mod;
            for(int j=i+1;j<=n-1;j++)v[i][j]=v[i][j-1]*a[j]%mod;
           }
           for(int i=2;i<=n;i++){
            c=c*a[i-1]%mod;
            Arrays.fill(dp[t],0);
            for(int j=2;j<2*(i-1);j++){
             dp[t][j]=dp[t^1][j-1]%mod;
            }
            dp[t][1]=1;
            for(int j=0;j<2*n-1;j++)ans[j]=(ans[j]+dp[t][j]*c%mod)%mod;
            for(int j=i-1;j>=1;j--){
             dp[t][2*(i-j)]=(dp[t][2*(i-j)]+v[j][i-1])%mod;
             ans[2*(i-j)]=(ans[2*(i-j)]+c*v[j][i-1]%mod*i2%mod)%mod;
            }
            t=t^1;
           }
           /*for(int i=2;i<=n;i++){
            c=(c*a[i-1])%mod;
            for(int j=i-1;j>=1;j--){
             long m=1;
             for(int k=i-j;k<=2*(i-j);k++){
              long v=c*m%mod;if(k==2*(i-j))v=v*i2%mod;//f(a[j])*a[j-1]%mod;
              ans[k]=(ans[k]+v)%mod;
              if(k==i-j)m=m*(a[j+k-(i-j)]-1+mod)%mod;
              else m=m*a[j+k-(i-j)]%mod;
             }
            }
           }*/
           for(int i=1;i<2*n-1;i++)out.print(ans[i]+" ");
          }
         /*pair ja[][];long w[];int from[],to[],c[];
             void make(int n,int m,InputReader in){
              ja=new pair[n+1][];w=new long[m];from=new int[m];to=new int[m];c=new int[n+1];
              for(int i=0;i<m;i++){
               int u=in.nextInt(),v=in.nextInt();long wt=in.nextLong();
               c[u]++;c[v]++;from[i]=u;to[i]=v;w[i]=wt;
              }
              for(int i=1;i<=n;i++){
               ja[i]=new pair[c[i]];c[i]=0;
              }
              for(int i=0;i<m;i++){
               ja[from[i]][c[from[i]]++]=new pair(to[i],w[i]);
               ja[to[i]][c[to[i]]++]=new pair(from[i],w[i]);
              }
             }*/
        int[] radixSort(int[] f){ return radixSort(f, f.length); }
	int[] radixSort(int[] f, int n)
	{
		int[] to = new int[n];
		{
			int[] b = new int[65537];
			for(int i = 0;i < n;i++)b[1+(f[i]&0xffff)]++;
			for(int i = 1;i <= 65536;i++)b[i]+=b[i-1];
			for(int i = 0;i < n;i++)to[b[f[i]&0xffff]++] = f[i];
			int[] d = f; f = to;to = d;
		}
		{
			int[] b = new int[65537];
			for(int i = 0;i < n;i++)b[1+(f[i]>>>16)]++;
			for(int i = 1;i <= 65536;i++)b[i]+=b[i-1];
			for(int i = 0;i < n;i++)to[b[f[i]>>>16]++] = f[i];
			int[] d = f; f = to;to = d;
		}
		return f;
	}
    }
    static class InputReader {
        BufferedReader br;
        StringTokenizer st;
        public InputReader(InputStream stream) {
            br = new BufferedReader(new InputStreamReader(stream));
            st = null;
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return null;
                st = new StringTokenizer(s);
            }
            return st.nextToken();
        }

        boolean hasMoreTokens() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return false;
                st = new StringTokenizer(s);
            }
            return true;
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }
        public long nextLong() {
            return Long.parseLong(next());
        }
        public double nextDouble() {
            return Double.parseDouble(next());
        }
    }
}