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 = (1 << 20) + 5, P = 998244353, R = 3;
int brev[N];
int w[N];
int mpow(int x, int k) {
  int ret = 1;
  while (k) {
    if (k & 1) ret = ret * (long long)x % P;
    k >>= 1;
    x = x * (long long)x % P;
  }
  return ret;
}
template <class It>
void fft(It a, int lgn, int sgn) {
  int n = 1 << lgn;
  for (int i = 0; i < n; ++i)
    if (i < brev[i]) swap(a[i], a[brev[i]]);
  for (int k = lgn - 1, t = 1; t < n; --k, t <<= 1) {
    for (int i = 0; i < n; i += t << 1) {
      for (int j = 0; j < t; ++j) {
        int a0 = a[i + j], a1 = a[i + j + t];
        a[i + j] = (a0 + w[j << k] * (long long)a1) % P;
        a[i + j + t] = (a0 + w[j << k] * (long long)(P - a1)) % P;
      }
    }
  }
  if (sgn == -1) {
    int nv = mpow(n, P - 2);
    reverse(a + 1, a + n);
    for (int i = 0; i < n; ++i) a[i] = a[i] * (long long)nv % P;
  }
}
vector<int> mult(const vector<int>& a, const vector<int>& b) {
  int n = (int)a.size() - 1, m = (int)b.size() - 1;
  int lgn = 0;
  while ((1 << lgn) <= n + m) ++lgn;
  int l = 1 << lgn;
  for (int i = 0; i < l; ++i)
    brev[i] = (brev[i >> 1] >> 1) | ((i & 1) << (lgn - 1));
  int root = mpow(R, (P - 1) / l);
  w[0] = 1;
  for (int i = 1; i < l; ++i) w[i] = w[i - 1] * (long long)root % P;
  static int ta[N], tb[N];
  memset(ta, 0, sizeof(int) << lgn);
  memset(tb, 0, sizeof(int) << lgn);
  for (int i = 0; i <= n; ++i) ta[i] = a[i];
  for (int i = 0; i <= m; ++i) tb[i] = b[i];
  fft(ta, lgn, 1);
  fft(tb, lgn, 1);
  for (int i = 0; i < l; ++i) ta[i] = ta[i] * (long long)tb[i] % P;
  fft(ta, lgn, -1);
  vector<int> ret(n + m + 1);
  for (int i = 0; i <= n + m; ++i) ret[i] = ta[i];
  return ret;
}
vector<int> polyinv(const vector<int>& a) {
  int n = (int)a.size() - 1;
  if (n == 0) return vector<int>(1, mpow(a[0], P - 2));
  int t = n / 2;
  vector<int> half = a;
  half.resize(t + 1);
  vector<int> g0 = polyinv(half), prod = mult(g0, a);
  prod.resize(n + 1);
  prod[0] = (P + 2 - prod[0]) % P;
  for (int i = 1; i <= n; ++i) prod[i] = (P - prod[i]) % P;
  vector<int> ret = mult(g0, prod);
  ret.resize(n + 1);
  return ret;
}
vector<int> polysqrt(const vector<int>& a) {
  int n = (int)a.size() - 1;
  if (n == 0) return vector<int>(1, 1);
  int t = n / 2;
  vector<int> half = a;
  half.resize(t + 1);
  vector<int> g0 = polysqrt(half);
  g0.resize(n + 1);
  vector<int> ans(n + 1), res = mult(a, polyinv(g0));
  for (int i = 0; i <= n; ++i)
    ans[i] = (g0[i] + res[i]) * (long long)((P + 1) >> 1) % P;
  return ans;
}
vector<int> pow(const vector<int>& a, int k) {
  int n = (int)a.size() - 1;
  int lgn = 0;
  while ((1 << lgn) <= n * k) ++lgn;
  static int ta[N];
  memset(ta, 0, sizeof(int) << lgn);
  memcpy(ta, a.begin().base(), sizeof(int) * (n + 1));
  int l = 1 << lgn;
  for (int i = 0; i < l; ++i)
    brev[i] = (brev[i >> 1] >> 1) | ((i & 1) << (lgn - 1));
  int root = mpow(R, (P - 1) / l);
  w[0] = 1;
  for (int i = 1; i < l; ++i) w[i] = w[i - 1] * (long long)root % P;
  fft(ta, lgn, 1);
  for (int i = 0; i < (1 << lgn); ++i) ta[i] = mpow(ta[i], k);
  fft(ta, lgn, -1);
  return vector<int>(ta, ta + n * k + 1);
}
vector<int> polyinvsqrt(const vector<int>& a) {
  int n = (int)a.size() - 1;
  if (n == 0) return vector<int>(1, 1);
  int t = n / 2;
  vector<int> half = a;
  half.resize(t + 1);
  vector<int> g0 = polyinvsqrt(half);
  vector<int> res = pow(g0, 3);
  res.resize(n + 1);
  res = mult(res, a);
  g0.resize(n + 1);
  vector<int> ans(n + 1);
  for (int i = 0; i <= n; ++i)
    ans[i] = (g0[i] * 3LL + (P - res[i])) % P * ((P + 1) >> 1) % P;
  return ans;
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  vector<int> c(m + 1);
  c[0] = 1;
  while (n--) {
    int k;
    scanf("%d", &k);
    if (k <= m) c[k] = P - 4;
  }
  vector<int> a = polyinvsqrt(polyinv(c));
  for (int i = 1; i <= m; ++i) a[i] = a[i] * (long long)((P + 1) >> 1) % P;
  vector<int> ans = polyinv(a);
  for (int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
  return 0;
}