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;
namespace ProjectPollyJr {
const int mod = 998244353;
int quickpow(int x, int y) {
  long long res = 1, base = x;
  while (y) {
    if (y & 1) res *= base, res %= mod;
    y >>= 1;
    base *= base, base %= mod;
  }
  return res;
}
int inv(int x) { return quickpow(x, mod - 2); }
const int nttg = 3;
const int invg = inv(nttg);
struct poly {
  vector<int> f;
  int &operator[](int n) { return f[n]; }
  const int &operator[](int n) const { return f[n]; }
  void resize(int n) { f.resize(n); }
  int size() const { return f.size(); }
  void rev() { reverse(f.begin(), f.end()); }
  void read(int n) {
    f.resize(n);
    for (int i = 0; i < n; i++) scanf("%d", &f[i]);
  }
  void out() {
    for (int i = 0; i < f.size(); i++) printf("%d ", f[i]);
    printf("\n");
  }
  void cpy(poly g, int c) {
    for (int i = 0; i < c; i++) f[i] = g[i];
  }
} R;
int init(int m) {
  int n = 1;
  for (; n < m; n <<= 1)
    ;
  return n;
}
void rev(poly &f) {
  int n = f.size();
  R.resize(n);
  for (int i = 0; i < n; i++) R[i] = (R[i >> 1] >> 1) | ((i & 1) ? n >> 1 : 0);
  for (int i = 0; i < n; i++)
    if (i < R[i]) swap(f[i], f[R[i]]);
}
poly operator+(poly f, int c) {
  f[0] = (f[0] + c) % mod;
  return f;
}
poly operator+(poly f, poly g) {
  for (int i = 0; i < f.size(); i++)
    f[i] = (f[i] + ((i < g.size()) ? g[i] : 0)) % mod;
  return f;
}
poly operator-(poly f, poly g) {
  for (int i = 0; i < f.size(); i++)
    f[i] = (f[i] - ((i < g.size()) ? g[i] : 0) + mod) % mod;
  return f;
}
poly operator*(poly f, int c) {
  for (int i = 0; i < f.size(); i++) f[i] = 1ll * f[i] * c % mod;
  return f;
}
void NTT(poly &f, int op) {
  int n = f.size();
  rev(f);
  for (int w = 2; w <= n; w <<= 1) {
    int len = w / 2;
    int tmp = quickpow((op == 1) ? nttg : invg, (mod - 1) / w);
    for (int k = 0; k < n; k += w) {
      int buf = 1;
      for (int l = k; l < k + len; l++) {
        int tt = 1ll * f[l + len] * buf % mod;
        f[l + len] = (f[l] - tt + mod) % mod;
        f[l] = (f[l] + tt) % mod;
        buf = 1ll * buf * tmp % mod;
      }
    }
  }
  if (op == -1) {
    int invn = inv(n);
    for (int i = 0; i < n; i++) f[i] = 1ll * f[i] * invn % mod;
  }
}
poly operator*(poly f, poly g) {
  int m = f.size() + g.size() - 1;
  int n = init(m);
  f.resize(n);
  g.resize(n);
  NTT(f, 1);
  NTT(g, 1);
  for (int i = 0; i < n; i++) f[i] = 1ll * f[i] * g[i] % mod;
  NTT(f, -1);
  f.resize(m);
  return f;
}
poly Inv(poly f, int m) {
  if (m == 1) {
    poly g;
    g.resize(1);
    g[0] = inv(f[0]);
    return g;
  }
  poly g = Inv(f, (m + 1) / 2), t;
  int n = init(m * 2);
  g.resize(n);
  t.resize(n);
  t.cpy(f, m);
  NTT(g, 1);
  NTT(t, 1);
  for (int i = 0; i < n; i++)
    g[i] = (2ll - 1ll * t[i] * g[i] % mod + mod) * g[i] % mod;
  NTT(g, -1);
  g.resize(m);
  return g;
}
poly operator~(poly f) { return Inv(f, f.size()); }
poly operator/(poly f, poly g) {
  int len = f.size() - g.size() + 1;
  f.rev(), g.rev();
  g.resize(len);
  f = f * (~g);
  f.resize(len);
  f.rev();
  return f;
}
poly operator%(poly f, poly g) {
  poly t = f / g;
  f = f - g * t;
  f.resize(g.size() - 1);
  return f;
}
poly diriviate(poly f) {
  int len = f.size();
  for (int i = 0; i < len - 1; i++) f[i] = 1ll * f[i + 1] * (i + 1) % mod;
  f.resize(len - 1);
  return f;
}
poly intergrate(poly f) {
  int len = f.size();
  f.resize(len + 1);
  for (int i = len; i >= 1; i--) f[i] = 1ll * f[i - 1] * inv(i) % mod;
  f[0] = 0;
  return f;
}
poly Ln(poly f) {
  poly g = diriviate(f), h = ~f;
  g = g * h;
  g.resize(f.size() - 1);
  return intergrate(g);
}
poly Exp(poly f, int m) {
  if (m == 1) {
    poly g;
    g.resize(1);
    g[0] = 1;
    return g;
  }
  poly g = Exp(f, (m + 1) / 2), t;
  g.resize(m);
  t.resize(m);
  t.cpy(f, m);
  g = g * (t - Ln(g) + 1);
  g.resize(m);
  return g;
}
poly Exp(poly f) { return Exp(f, f.size()); }
poly Pow(poly f, int x, int y) {
  poly g = Ln(f);
  g = g * x;
  g = g * inv(y);
  return Exp(g);
}
}  // namespace ProjectPollyJr
using namespace ProjectPollyJr;
signed main() {
  int n, m;
  scanf("%d%d", &n, &m);
  poly c;
  c.resize(m + 1);
  for (int i = 1; i <= n; i++) {
    int x;
    scanf("%d", &x);
    if (x <= m) c[x] = 1;
  }
  poly ans = (~(Pow((c * (-4) + 1), 1, 2) + 1)) * 2;
  for (int i = 1; i <= m; i++) printf("%d\n", ans[i]);
  return 0;
}