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 maxn = 3e5;
const long long mod = 998244353;
const long long inv2 = 499122177;
const int g = 3;
typedef int coefficients[maxn];
inline int __usr_clz(int v) {
  return v < 2 ? v + 1 : 1 << (33 - __builtin_clz(v - 1));
}
inline int __usr_fpw(int p, int e) {
  if (e == 0) return 1;
  long long ret = __usr_fpw(p, e >> 1);
  ret = ret * ret % mod;
  if (e & 1) ret = ret * p % mod;
  return ret;
}
inline int __usr_inv(int p) { return __usr_fpw(p, mod - 2); }
struct polynomial {
  coefficients val;
  int len;
  polynomial(int v) {
    memset(val, 0, sizeof(coefficients));
    val[0] = v;
    len = 1;
  }
  polynomial(int v[]) {
    for ((len) = (maxn - 1); (len > 0 && v[len - 1] == 0); (len)--)
      val[len] = 0;
    val[len] = 0;
    static int i;
    for ((i) = (0); (i) <= (len - 1); (i)++) val[i] = v[i];
  }
  polynomial() {
    memset(val, 0, sizeof(coefficients));
    len = 0;
  }
  void init(int v) {
    memset(val, 0, sizeof(coefficients));
    val[0] = v;
    len = 1;
  }
  void init(int v[]) {
    for ((len) = (maxn - 1); (len > 0 && v[len - 1] == 0); (len)--)
      val[len] = 0;
    val[len] = 0;
    static int i;
    for ((i) = (0); (i) <= (len - 1); (i)++) val[i] = v[i];
  }
  void init() {
    memset(val, 0, sizeof(coefficients));
    len = 0;
  }
  void reinit(int v = -1) {
    if (v >= 0) {
      len = v;
      return;
    }
    for ((len) = (maxn - 1); (len > 0 && val[len - 1] == 0); (len)--)
      ;
  }
  void reverse() {
    static int i;
    for ((i) = (0); (i) <= ((len >> 1) - 1); (i)++)
      val[i] ^= val[len - 1 - i] ^= val[i] ^= val[len - 1 - i];
  }
  void reserve(int v = 0) {
    len = v;
    static int i;
    for ((i) = (v); (i) <= (len - 1); (i)++) val[i] = 0;
  }
  void output(int rev = 0) {
    static int i;
    if (rev)
      for ((i) = (0); (i) <= (len - 1); (i)++)
        printf(i < len - 1 ? "%d " : "%d\n", val[i]);
    else
      for ((i) = (len - 1); (i) >= (0); (i)--)
        printf(i ? "%d " : "%d\n", val[i]);
  }
  void output_len(int v, int rev = 0) {
    static int i;
    if (rev)
      for ((i) = (0); (i) <= (v - 1); (i)++)
        printf(i < v - 1 ? "%d " : "%d\n", val[i]);
    else
      for ((i) = (v - 1); (i) >= (0); (i)--) printf(i ? "%d " : "%d\n", val[i]);
  }
};
polynomial operator+(polynomial &x, polynomial &y);
polynomial operator-(polynomial &x, polynomial &y);
polynomial operator*(polynomial &x, polynomial &y);
polynomial operator~(polynomial &x);
polynomial operator^(polynomial &x, int y);
polynomial operator/(polynomial &x, polynomial &y);
polynomial operator%(polynomial &x, polynomial &y);
bool operator==(polynomial &x, polynomial &y);
bool operator!=(polynomial &x, polynomial &y);
namespace NTT {
int dft_len, dft_len_inv;
coefficients V, X, Y;
coefficients B, B0;
void dft(int A[], int p) {
  static int i, j, k;
  static long long x, y;
  j = 0;
  for ((i) = (0); (i) <= (dft_len - 1); (i)++) {
    if (i > j) A[i] ^= A[j] ^= A[i] ^= A[j];
    for ((k) = (dft_len >> 1); ((j ^= k) < k); (k) >>= 1)
      ;
  }
  for ((i) = (0); (i) <= (dft_len - 1); (i)++) V[i] = A[i];
  for ((i) = (2); (i) <= (dft_len); (i) <<= 1) {
    int gn = __usr_fpw(g, (mod - 1) / i);
    for ((j) = (0); (j) <= (dft_len - 1); (j) += (i)) {
      int G = 1;
      for ((k) = (j); (k) <= (j + (i >> 1) - 1); (k)++) {
        x = V[k];
        y = (long long)V[k + (i >> 1)] * G % mod;
        V[k] = (x + y) % mod;
        V[k + (i >> 1)] = (x - y + mod) % mod;
        G = (long long)G * gn % mod;
      }
    }
  }
  if (p == -1) {
    for ((i) = (1); (i) <= ((dft_len >> 1) - 1); (i)++)
      V[i] ^= V[dft_len - i] ^= V[i] ^= V[dft_len - i];
    dft_len_inv = __usr_inv(dft_len);
    for ((i) = (0); (i) <= (dft_len - 1); (i)++)
      V[i] = (long long)V[i] * dft_len_inv % mod;
  }
  for ((i) = (0); (i) <= (dft_len - 1); (i)++) A[i] = V[i];
}
void inv(int A[], int len, int A0[] = X, int dep = 1) {
  if (len <= 0) return;
  if (len == 1) {
    memset(A0, 0, sizeof(coefficients));
    A0[0] = __usr_inv(A[0]);
    if (dep == 1) memcpy(A, A0, sizeof(coefficients));
    return;
  }
  inv(A, (len + 1) >> 1, A0, dep + 1);
  dft_len = __usr_clz(len + 1);
  dft_len_inv = __usr_inv(dft_len);
  static int i;
  for ((i) = (0); (i) <= (len - 1); (i)++) Y[i] = A[i];
  for ((i) = (len); (i) <= (dft_len - 1); (i)++) Y[i] = 0;
  dft(Y, 1);
  dft(A0, 1);
  for ((i) = (0); (i) <= (dft_len - 1); (i)++)
    A0[i] = (long long)A0[i] * (mod + 2 - (long long)Y[i] * A0[i] % mod) % mod;
  dft(A0, -1);
  for ((i) = (len); (i) <= (dft_len - 1); (i)++) A0[i] = 0;
  if (dep == 1) memcpy(A, A0, sizeof(coefficients));
}
void root(int A[], int len, int A0[] = X, int dep = 1) {
  if (len <= 0) return;
  if (len == 1) {
    memset(A0, 0, sizeof(coefficients));
    A0[0] = 1;
    if (dep == 1) memcpy(A, A0, sizeof(coefficients));
    return;
  }
  root(A, (len + 1) >> 1, A0, dep + 1);
  static int i;
  for ((i) = (0); (i) <= (len - 1); (i)++) B[i] = A0[i];
  inv(B, len, B0);
  dft_len = __usr_clz(len + 1);
  dft_len_inv = __usr_inv(dft_len);
  dft(B, 1);
  for ((i) = (0); (i) <= (len - 1); (i)++) Y[i] = A[i];
  for ((i) = (len); (i) <= (dft_len - 1); (i)++) Y[i] = 0;
  dft(Y, 1);
  dft(A0, 1);
  for ((i) = (0); (i) <= (dft_len - 1); (i)++)
    A0[i] = (inv2 * A0[i] + inv2 * Y[i] % mod * B[i]) % mod;
  dft(A0, -1);
  for ((i) = (len); (i) <= (dft_len - 1); (i)++) A0[i] = 0;
  if (dep == 1) memcpy(A, A0, sizeof(coefficients));
}
}  // namespace NTT
polynomial operator+(polynomial &x, polynomial &y) {
  static int i;
  int rep_len = max(x.len, y.len);
  static coefficients res;
  memset(res, 0, sizeof(coefficients));
  for ((i) = (0); (i) <= (rep_len - 1); (i)++)
    res[i] = (x.val[i] + y.val[i]) % mod;
  return polynomial(res);
}
polynomial operator-(polynomial &x, polynomial &y) {
  static int i;
  int rep_len = max(x.len, y.len);
  static coefficients res;
  memset(res, 0, sizeof(coefficients));
  for ((i) = (0); (i) <= (rep_len - 1); (i)++)
    res[i] = (mod + (x.val[i] - y.val[i]) % mod) % mod;
  return polynomial(res);
}
polynomial operator*(polynomial &x, polynomial &y) {
  static coefficients res, a, b;
  memset(res, 0, sizeof(coefficients));
  memset(a, 0, sizeof(coefficients));
  memset(b, 0, sizeof(coefficients));
  NTT::dft_len = max(__usr_clz(x.len), __usr_clz(y.len));
  static int i;
  for ((i) = (0); (i) <= (x.len - 1); (i)++) a[i] = x.val[i];
  for ((i) = (0); (i) <= (y.len - 1); (i)++) b[i] = y.val[i];
  NTT::dft(a, 1);
  NTT::dft(b, 1);
  for ((i) = (0); (i) <= (NTT::dft_len - 1); (i)++)
    res[i] = (long long)a[i] * b[i] % mod;
  NTT::dft(res, -1);
  return polynomial(res);
}
polynomial operator~(polynomial &x) {
  static polynomial res;
  res = x;
  NTT::inv(res.val, res.len);
  res.reinit();
  return res;
}
polynomial operator^(polynomial &x, int y) {
  static polynomial res;
  res = x;
  NTT::inv(res.val, y);
  res.reinit();
  return res;
}
polynomial operator!(polynomial &x) {
  static polynomial res;
  res = x;
  NTT::root(res.val, res.len);
  res.reinit();
  return res;
}
polynomial operator/(polynomial &x, polynomial &y) {
  static polynomial res;
  x.reverse();
  y.reverse();
  res = y ^ (x.len - y.len + 1);
  res = x * res;
  res.reserve(x.len - y.len + 1);
  res.reverse();
  x.reverse();
  y.reverse();
  return res;
}
polynomial operator%(polynomial &x, polynomial &y) {
  static polynomial res;
  res = x / y;
  res = res * y;
  res = x - res;
  return res;
}
bool operator==(polynomial &x, polynomial &y) {
  if (x.len != y.len) return 0;
  static int i;
  for ((i) = (0); (i) <= (x.len - 1); (i)++)
    if (x.val[i] != y.val[i]) return 0;
  return 1;
}
bool operator!=(polynomial &x, polynomial &y) { return !(x == y); }
int n, m;
int a[maxn];
polynomial p;
int main() {
  scanf("%d%d", &n, &m);
  int i, j;
  for ((i) = (1); (i) <= (n); (i)++) {
    scanf("%d", &j);
    if (j <= m) a[j] = (a[j] + mod - 4) % mod;
  }
  a[0] = 1;
  p.init(a);
  p.reinit(m + 1);
  p = !p;
  p.val[0] = (p.val[0] + 1) % mod;
  p = ~p;
  for ((i) = (1); (i) <= (m); (i)++) printf("%lld\n", (p.val[i] * 2) % mod);
  return 0;
}