Problem: Our child likes computer science very much, especially he likes binary trees.

Consider the sequence of n distinct positive integers: c1, c2, ..., cn. The child calls a vertex-weighted rooted binary tree good if and only if for every vertex v, the weight of v is in the set {c1, c2, ..., cn}. Also our child thinks that the weight of a vertex-weighted tree is the sum of all vertices' weights.

Given an integer m, can you for all s (1 ≤ s ≤ m) calculate the number of good vertex-weighted rooted binary trees with weight s? Please, check the samples for better understanding what trees are considered different.

We only want to know the answer modulo 998244353 (7 × 17 × 223 + 1, a prime number).

Input

The first line contains two integers n, m (1 ≤ n ≤ 105; 1 ≤ m ≤ 105). The second line contains n space-separated pairwise distinct integers c1, c2, ..., cn. (1 ≤ ci ≤ 105).

Output

Print m lines, each line containing a single integer. The i-th line must contain the number of good vertex-weighted rooted binary trees whose weight exactly equal to i. Print the answers modulo 998244353 (7 × 17 × 223 + 1, a prime number).

Examples

Input

2 3
1 2


Output

1
3
9


Input

3 10
9 4 3


Output

0
0
1
1
0
2
4
2
6
15


Input

5 10
13 10 6 4 15


Output

0
0
0
1
0
1
0
2
0
5

Note

In the first example, there are 9 good vertex-weighted rooted binary trees whose weight exactly equal to 3:

<image>

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5;
const int ARR_DEPTH = 1 << 19;
long long temp[20][ARR_DEPTH + 1];
const long long MOD = 998244353;
struct GF_Manager {
  int tC = 0;
  stack<int> to_be_freed;
  const static long long DEPTH = 23;
  long long primitives[DEPTH + 1];
  long long primitives_inv[DEPTH + 1];
  long long two_inv[DEPTH + 1];
  long long mod_pow(long long base, long long exp) {
    if (exp == 0) return 1;
    if (exp & 1)
      return (base * mod_pow(base, exp - 1)) % MOD;
    else
      return mod_pow((base * base) % MOD, exp / 2);
  }
  void set_up_primitives() {
    primitives[DEPTH] = 31;
    primitives_inv[DEPTH] = mod_pow(primitives[DEPTH], MOD - 2);
    two_inv[DEPTH] = mod_pow(1 << DEPTH, MOD - 2);
    for (int n = DEPTH - 1; n >= 0; n--)
      primitives[n] = (primitives[n + 1] * primitives[n + 1]) % MOD,
      primitives_inv[n] = mod_pow(primitives[n], MOD - 2),
      two_inv[n] = mod_pow(1 << n, MOD - 2);
  }
  GF_Manager() { set_up_primitives(); }
  void start_claiming() { to_be_freed.push(0); }
  long long* claim() {
    ++to_be_freed.top();
    return temp[tC++];
  }
  void end_claiming() {
    tC -= to_be_freed.top();
    to_be_freed.pop();
  }
  void clean(long long A[], int an, bool deep_cleaning = false) {
    if (deep_cleaning)
      for (int i = 0; i < an; i++) A[i] %= MOD;
    for (int i = 0; i < an; i++)
      if (A[i] < 0) A[i] += MOD;
  }
  void NTT(int offset, long long A[], int n, long long t[],
           bool is_inverse = false) {
    if (n == 0) return;
    for (int i = 0; i < (1 << (n - 1)); i++) {
      t[i] = A[offset + 2 * i];
      t[i + (1 << (n - 1))] = A[offset + 2 * i + 1];
    }
    for (int i = 0; i < (1 << n); i++) A[offset + i] = t[i];
    NTT(offset, A, n - 1, t, is_inverse);
    NTT(offset + (1 << (n - 1)), A, n - 1, t, is_inverse);
    long long w1 = is_inverse ? primitives_inv[n] : primitives[n];
    long long w = 1;
    for (int i = 0; i < (1 << (n - 1)); i++, w = (w * w1) % MOD) {
      t[i] = (A[offset + i] + w * A[offset + (1 << n - 1) + i]) % MOD;
      t[i + (1 << (n - 1))] =
          (A[offset + i] - w * A[offset + (1 << n - 1) + i]) % MOD;
    }
    for (int i = 0; i < (1 << n); i++) A[offset + i] = t[i];
  }
  int add(long long A[], int an, long long B[], int bn, long long C[]) {
    int cn = 0;
    for (int i = 0; i < max(an, bn); i++) {
      C[i] = A[i] + B[i];
      if (C[i] <= -MOD) C[i] += MOD;
      if (MOD <= C[i]) C[i] -= MOD;
      if (C[i] != 0) cn = i;
    }
    return cn;
  }
  int subtract(long long A[], int an, long long B[], int bn, long long C[]) {
    int cn = 0;
    for (int i = 0; i < max(an, bn); i++) {
      C[i] = A[i] - B[i];
      if (C[i] <= -MOD) C[i] += MOD;
      if (MOD <= C[i]) C[i] -= MOD;
      if (C[i] != 0) cn = i;
    }
    return cn;
  }
  int scalar_mult(long long v, long long A[], int an, long long C[]) {
    for (int i = 0; i < an; i++) C[i] = (v * A[i]) % MOD;
    return v == 0 ? 0 : an;
  }
  int mult(long long A[], int an, long long B[], int bn, long long C[]) {
    start_claiming();
    int n, degree = an + bn - 1;
    for (n = 0; (1 << n) < degree; n++)
      ;
    long long* tA = claim();
    long long* tB = claim();
    long long* t = claim();
    copy(A, A + an, tA);
    fill(tA + an, tA + (1 << n), 0);
    copy(B, B + bn, tB);
    fill(tB + bn, tB + (1 << n), 0);
    NTT(0, tA, n, t);
    NTT(0, tB, n, t);
    for (int i = 0; i < (1 << n); i++) tA[i] = (tA[i] * tB[i]) % MOD;
    NTT(0, tA, n, t, true);
    scalar_mult(two_inv[n], tA, degree, C);
    end_claiming();
    return degree;
  }
  int reciprocal(long long F[], int fn, long long R[]) {
    start_claiming();
    long long* tR = claim();
    long long* tF = claim();
    long long* tempR = claim();
    int n;
    for (n = 0; (1 << n) < fn; n++)
      ;
    copy(F, F + fn, tF);
    fill(tempR, tempR + (1 << n), 0);
    tempR[0] = mod_pow(tF[0], MOD - 2);
    for (int i = 1; i <= n; i++) {
      mult(tempR, 1 << i, tF, 1 << i, tR);
      tR[0] -= 2;
      scalar_mult(-1, tR, 1 << i, tR);
      mult(tempR, 1 << i, tR, 1 << i, tempR);
    }
    copy(tempR, tempR + fn, R);
    end_claiming();
    return n;
  }
  int square_root(long long F[], int fn, long long S[]) {
    start_claiming();
    long long* tS = claim();
    long long* tF = claim();
    long long* tempS = claim();
    int n;
    for (n = 0; (1 << n) < fn; n++)
      ;
    copy(F, F + fn, tF);
    fill(tempS, tempS + (1 << n), 0);
    tempS[0] = 1;
    for (int i = 1; i <= n; i++) {
      reciprocal(tempS, 1 << i, tS);
      mult(tF, 1 << i, tS, 1 << i, tS);
      add(tempS, 1 << i, tS, 1 << i, tempS);
      scalar_mult(two_inv[1], tempS, 1 << i, tempS);
    }
    copy(tempS, tempS + fn, S);
    end_claiming();
    return n;
  }
  int binary_splitting(int l, int r, long long target[], int offset = 0) {
    if (l == r) {
      target[offset] = l + 1;
      target[offset + 1] = 1;
      return 2;
    }
    int m = (l + r) / 2;
    int da = binary_splitting(l, m, target, offset);
    int db = binary_splitting(m + 1, r, target, offset + da);
    return mult(target + offset, da, target + offset + da, db, target + offset);
  }
  int quotient(long long F[], int fn, long long G[], int gn, long long Q[]) {
    start_claiming();
    long long* revF = claim();
    long long* revG = claim();
    long long* tempQ = claim();
    copy(F, F + fn, revF);
    reverse(revF, revF + fn);
    copy(G, G + gn, revG);
    reverse(revG, revG + gn);
    int qn = fn - gn + 1;
    reciprocal(revG, qn, revG);
    mult(revF, qn, revG, qn, tempQ);
    reverse(tempQ, tempQ + qn);
    copy(tempQ, tempQ + qn, Q);
    end_claiming();
    return qn;
  }
  int mod(long long F[], int fn, long long G[], int gn, long long R[]) {
    start_claiming();
    long long* Q = claim();
    long long* GQ = claim();
    int qn = quotient(F, fn, G, gn, Q);
    int gqn = mult(G, gn, Q, qn, GQ);
    int rn = subtract(F, fn, GQ, gqn, R);
    end_claiming();
    return rn;
  }
  int derivative(long long F[], int fn, long long F_[]) {
    for (long long i = 0; i < fn - 1; i++) F_[i] = ((i + 1) * F[i + 1]) % MOD;
    return fn - 1;
  }
};
GF_Manager gfManager;
long long F[(1 << 18) + 2];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n, m;
  cin >> n >> m;
  fill(F, F + m + 1, 0);
  F[0] = 1;
  for (int i = 0; i < n; i++) {
    int c;
    cin >> c;
    F[c] = -4;
  }
  gfManager.square_root(F, m + 1, F);
  F[0] += 1;
  gfManager.reciprocal(F, m + 1, F);
  gfManager.scalar_mult(2, F, m + 1, F);
  gfManager.clean(F, m + 1);
  for (int i = 1; i <= m; i++) cout << F[i] << endl;
  cout << flush;
  return 0;
}