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 int64 = long long;
using uchar = unsigned char;
constexpr int mxdg(262144);
constexpr int p(998244353);
constexpr int hfp(p >> 1);
constexpr int proot(3);
using poly_t = int[mxdg];
using poly = int* const;
template <class _Tp>
inline void swap(_Tp& x, _Tp& y) {
  _Tp z = x;
  x = y;
  y = z;
}
template <class _Tp>
inline int fpow(_Tp v, int n) {
  int pw = 1;
  for (; n; n >>= 1, v = (int64)v * v % p)
    if (n & 1) pw = (int64)pw * v % p;
  return pw;
}
template <class _Tp>
inline int fpow2(_Tp v, int n) {
  int pw = 1;
  for (; n; n >>= 1, v = (int64)v * v % (p - 1))
    if (n & 1) pw = (int64)pw * v % (p - 1);
  return pw;
}
template <class _Tpx, class _Tpy>
inline void inc(_Tpx& x, const _Tpy& y) {
  (p - y <= x) ? (x += y - p) : (x += y);
}
template <class _Tpx, class _Tpy>
inline void dec(_Tpx& x, const _Tpy& y) {
  x -= y;
  (x < 0) && (x += p);
}
template <class _Tpx, class _Tpy>
inline _Tpx pls(const _Tpx& x, const _Tpy& y) {
  return (x < p - y) ? (x + y) : (x - p + y);
}
template <class _Tpx, class _Tpy>
inline _Tpx sub(const _Tpx& x, const _Tpy& y) {
  return (x < y) ? (x - y + p) : (x - y);
}
template <class _Tp>
inline int div2(const _Tp& v) {
  return (v & 1) ? (v + p) >> 1 : (v >> 1);
}
template <class _Tp>
inline _Tp Max(const _Tp& x, const _Tp& y) {
  return x > y ? x : y;
}
namespace IOManager {
constexpr int FILESZ(131072);
char buf[FILESZ];
const char *ibuf = buf, *tbuf = buf;
struct IOManager {
  inline char gc() {
    return (ibuf == tbuf) &&
                   (tbuf = (ibuf = buf) + fread(buf, 1, FILESZ, stdin),
                    ibuf == tbuf)
               ? EOF
               : *ibuf++;
  }
  template <class _Tp>
  inline operator _Tp() {
    _Tp s = 0u;
    char c = gc();
    for (; c < 48; c = gc())
      ;
    for (; c > 47; c = gc()) s = (_Tp)(s * 10u + c - 48u);
    return s;
  }
};
}  // namespace IOManager
IOManager::IOManager io;
inline int calcpw2(const int& n) {
  int pw2 = 1;
  for (; pw2 < n; pw2 += pw2)
    ;
  return pw2;
}
int wn[mxdg], iwn[mxdg], inv[mxdg + 1];
inline void init_wn() {
  const int ob = fpow(proot, (p - 1) / mxdg);
  const int iob = fpow(ob, p - 2);
  wn[0] = iwn[0] = 1;
  for (int i = 1, v = 1, iv = 1; i != mxdg; ++i) {
    v = (int64)v * ob % p;
    wn[i] = v;
    iv = (int64)iv * iob % p;
    iwn[i] = iv;
  }
}
inline void init_inv() {
  inv[0] = inv[1] = 1;
  for (int i = 2; i <= mxdg; ++i) inv[i] = (int64)inv[p % i] * (p - p / i) % p;
}
void DFT(poly& A, const int& deg) {
  for (int i = 0, j = 0; i != deg; ++i) {
    if (i < j) swap(A[i], A[j]);
    for (int k = deg >> 1; (j ^= k) < k; k >>= 1)
      ;
  }
  int* const td = A + deg;
  for (int l = 1, tp = mxdg >> 1; l < deg; l += l, tp >>= 1)
    for (int *i = A, z; i < td; i += l + l)
      for (int j = 0, *w = wn; j != l; ++j, w += tp)
        z = (int64)i[j + l] * *w % p, i[j + l] = sub(i[j], z), inc(i[j], z);
}
void IDFT(poly& A, const int& deg) {
  for (int i = 0, j = 0; i != deg; ++i) {
    if (i < j) swap(A[i], A[j]);
    for (int k = deg >> 1; (j ^= k) < k; k >>= 1)
      ;
  }
  int* const td = A + deg;
  for (int l = 1, tp = mxdg >> 1; l < deg; l += l, tp >>= 1)
    for (int *i = A, z; i < td; i += l + l)
      for (int j = 0, *w = iwn; j != l; ++j, w += tp)
        z = (int64)i[j + l] * *w % p, i[j + l] = sub(i[j], z), inc(i[j], z);
  const int invdeg = fpow(deg, p - 2);
  for (int i = 0; i != deg; ++i) A[i] = (int64)A[i] * invdeg % p;
}
inline void cp(const int* const& sl, const int* const& sr, int* const& dl,
               int* const& dr) {
  std::copy(sl, sr, dl);
  if (sr - sl < dr - dl) std::fill(dl + (sr - sl), dr, 0);
}
void polyinv(const poly& h, poly& f, const int& n) {
  static poly_t inv_t;
  if (n == 1) return (void)(f[0] = fpow(h[0], p - 2));
  polyinv(h, f, (n + 1) >> 1);
  const int deg = calcpw2(n + n + 3);
  cp(h, h + n, inv_t, inv_t + deg);
  DFT(inv_t, deg);
  DFT(f, deg);
  for (int i = 0; i != deg; ++i)
    f[i] = (int64)f[i] * sub(2ll, (int64)f[i] * inv_t[i] % p) % p;
  IDFT(f, deg);
  std::fill(f + n, f + deg, 0);
}
void polyder(const poly& f, poly& df, const int& n) {
  for (int i = 1; i != n; ++i) df[i - 1] = (int64)f[i] * i % p;
}
void polyint(const poly& f, poly& intf, const int& n) {
  for (int i = n - 1; i; --i) intf[i] = (int64)f[i - 1] * inv[i] % p;
  intf[0] = 0;
}
void polyln(const poly& h, poly& f, const int& n) {
  static poly_t ln_t;
  const int deg = calcpw2(n + n + 3);
  std::fill(f + n - 1, f + deg, 0);
  polyder(h, f, n);
  std::fill(ln_t, ln_t + deg, 0);
  polyinv(h, ln_t, n);
  DFT(ln_t, deg);
  DFT(f, deg);
  for (int i = 0; i != deg; ++i) ln_t[i] = (int64)f[i] * ln_t[i] % p;
  IDFT(ln_t, deg);
  polyint(ln_t, f, n);
  std::fill(f + n, f + deg, 0);
}
void polyexp(const poly& h, poly& f, const int& n) {
  static poly_t exp_t;
  if (n == 1) return (void)(f[0] = 1);
  polyexp(h, f, (n + 1) >> 1);
  polyln(f, exp_t, n);
  for (int i = 0; i != n; ++i) exp_t[i] = sub(h[i], exp_t[i]);
  inc(exp_t[0], 1);
  const int deg = calcpw2(n + n + 3);
  DFT(f, deg);
  DFT(exp_t, deg);
  for (int i = 0; i != deg; ++i) f[i] = (int64)f[i] * exp_t[i] % p;
  IDFT(f, deg);
  std::fill(f + n, f + deg, 0);
}
void polydiv(const poly& f, const int& n, const poly& g, const int& m, poly& Q,
             poly& R) {
  static poly_t div_t;
  const int res = n - m + 1;
  const int deg1 = calcpw2(res + res);
  std::reverse_copy(g, g + m, Q);
  if (m < deg1) std::fill(Q + m, Q + deg1, 0);
  polyinv(Q, div_t, res);
  std::reverse_copy(f + m - 1, f + n, Q);
  std::fill(Q + res, Q + deg1, 0);
  DFT(Q, deg1);
  DFT(div_t, deg1);
  for (int i = 0; i != deg1; ++i) Q[i] = (int64)Q[i] * div_t[i] % p;
  IDFT(Q, deg1);
  std::reverse(Q, Q + res);
  std::fill(Q + res, Q + deg1, 0);
  const int deg2 = calcpw2(n);
  cp(Q, Q + res, R, R + deg2);
  cp(g, g + m, div_t, div_t + deg2);
  DFT(R, deg2);
  DFT(div_t, deg2);
  for (int i = 0; i != deg2; ++i) R[i] = (int64)R[i] * div_t[i] % p;
  IDFT(R, deg2);
  for (int i = 0; i != m; ++i) R[i] = sub(f[i], R[i]);
  std::fill(R + m - 1, R + deg2, 0);
}
void polysqrt(const poly& h, poly& f, const int& n) {
  static poly_t sqrt1_t, sqrt2_t;
  if (n == 1) return (void)(f[0] = 1);
  polysqrt(h, f, (n + 1) >> 1);
  const int deg = calcpw2(n + n + 3);
  std::fill(sqrt1_t, sqrt1_t + deg, 0);
  polyinv(f, sqrt1_t, n);
  cp(h, h + n, sqrt2_t, sqrt2_t + deg);
  DFT(sqrt1_t, deg);
  DFT(sqrt2_t, deg);
  for (int i = 0; i != deg; ++i)
    sqrt1_t[i] = (int64)sqrt1_t[i] * sqrt2_t[i] % p;
  IDFT(sqrt1_t, deg);
  for (int i = (n + 1) >> 1; i != n; ++i) f[i] = div2(sqrt1_t[i]);
}
void polypow(const poly& h, poly& f, const int& k, const int& n) {
  static poly_t pow_t;
  if (h[0] == 1) {
    polyln(h, pow_t, n);
    for (int i = 0; i != n; ++i) pow_t[i] = (int64)pow_t[i] * k % p;
    std::fill(f, f + n, 0);
    polyexp(pow_t, f, n);
  } else {
    int lw = 0;
    for (; !h[lw]; ++lw)
      ;
    const int low = lw, lowc = h[lw], ilowc = fpow(lowc, p - 2);
    for (int i = 0; i != n - low; ++i) pow_t[i] = (int64)h[i + low] * ilowc % p;
    polyln(pow_t, f, n);
    for (int i = 0; i != n; ++i) f[i] = (int64)f[i] * k % p;
    std::fill(pow_t, pow_t + n, 0);
    polyexp(f, pow_t, n);
    const int pwlow = low * k, pwlowc = fpow(lowc, k);
    for (int i = 0; i != n - pwlow; ++i)
      f[i + pwlow] = (int64)pow_t[i] * pwlowc % p;
    std::fill(f, f + pwlow, 0);
  }
}
poly_t f, g;
int main() {
  init_wn();
  int n = io;
  const int m = (int)io + 1;
  f[0] = 1;
  for (int i; n; --n)
    if ((i = io) < m) f[i] = p - 4;
  polysqrt(f, g, m);
  inc(g[0], 1);
  std::fill(f, f + m, 0);
  polyinv(g, f, m);
  for (int i = 1; i != m; ++i)
    printf("%d\n", f[i] <= hfp ? f[i] + f[i] : (f[i] + f[i] - p));
  return 0;
}