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>
#pragma GCC optmize(2)
using namespace std;
constexpr int maxn = 4e5 + 100, mod = 998244353, G = 3, invG = 332748118,
              inf = 0x7fffffff;
constexpr inline int add(const int a, const int b) { return (a + b) % mod; }
constexpr inline int sub(const int a, const int b) {
  return (a - b + mod) % mod;
}
constexpr inline int mul(const int a, const int b) {
  return (1ll * a * b) % mod;
}
inline int qpow(int base, int b) {
  int res = 1;
  while (b) {
    if (b & 1) res = mul(res, base);
    base = mul(base, base);
    b >>= 1;
  }
  return res;
}
inline int inv(const int x) { return qpow(x, mod - 2); }
struct IO {
 private:
  static constexpr int ibufsiz = 1 << 20;
  char ibuf[ibufsiz + 1], *inow = ibuf, *ied = ibuf;
  static constexpr int obufsiz = 1 << 20;
  char obuf[obufsiz + 1], *onow = obuf;
  const char *oed = obuf + obufsiz;

 public:
  inline char getchar() {
    if (inow == ied) {
      ied = ibuf + sizeof(char) * fread(ibuf, sizeof(char), ibufsiz, stdin);
      *ied = '\0';
      inow = ibuf;
    }
    return *inow++;
  }
  template <typename T>
  inline void read(T &x) {
    static bool flg;
    flg = 0;
    x = 0;
    char c = getchar();
    while (!isdigit(c)) flg = c == '-' ? 1 : flg, c = getchar();
    while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
    if (flg) x = -x;
  }
  template <typename T, typename... Y>
  inline void read(T &x, Y &...X) {
    read(x);
    read(X...);
  }
  inline int readi() {
    static int res;
    read(res);
    return res;
  }
  inline long long readll() {
    static long long res;
    read(res);
    return res;
  }
  inline void flush() {
    fwrite(obuf, sizeof(char), onow - obuf, stdout);
    fflush(stdout);
    onow = obuf;
  }
  inline void putchar(char c) {
    *onow++ = c;
    if (onow == oed) {
      fwrite(obuf, sizeof(char), obufsiz, stdout);
      onow = obuf;
    }
  }
  template <typename T>
  inline void write(T x, char split = '\0') {
    static unsigned char buf[64];
    if (x < 0) putchar('-'), x = -x;
    int p = 0;
    do {
      buf[++p] = x % 10;
      x /= 10;
    } while (x);
    for (int i = p; i >= 1; i--) putchar(buf[i] + '0');
    if (split != '\0') putchar(split);
  }
  inline void lf() { putchar('\n'); }
  ~IO() { fwrite(obuf, sizeof(char), onow - obuf, stdout); }
} io;
template <typename A, typename B>
inline void chkmin(A &x, const B &y) {
  if (y < x) x = y;
}
template <typename A, typename B>
inline void chkmax(A &x, const B &y) {
  if (y > x) x = y;
}
int tr[maxn << 1], len = 1;
struct poly : std::vector<int> {
  using std::vector<int>::vector;
  inline void ntt(const int flg = 1) {
    const int n = size();
    for (int i = 0; i < n; i++)
      if (i < tr[i]) std::swap((*this)[i], (*this)[tr[i]]);
    for (int p = 2; p <= n; p <<= 1) {
      const int unit = qpow(flg == 1 ? G : invG, (mod - 1) / p);
      const int len = p >> 1;
      for (int k = 0; k < n; k += p) {
        int now = 1;
        for (int l = k; l < k + len; l++) {
          const int tt = mul((*this)[l + len], now);
          (*this)[l + len] = sub((*this)[l], tt);
          (*this)[l] = add((*this)[l], tt);
          now = mul(now, unit);
        }
      }
    }
    if (flg == -1) {
      const int inv = ::inv(n);
      for (int i = 0; i < n; i++) (*this)[i] = mul((*this)[i], inv);
    }
  }
  poly operator+(const poly &g) const {
    poly res;
    res.resize(size());
    for (unsigned int i = 0; i < size(); i++) res[i] = add((*this)[i], g[i]);
    return res;
  }
  poly operator*(const poly &g) const {
    poly res;
    res.resize(size());
    for (unsigned int i = 0; i < size(); i++) res[i] = mul((*this)[i], g[i]);
    return res;
  }
  poly operator*(const int g) const {
    poly res;
    res.resize(size());
    for (unsigned int i = 0; i < size(); i++) res[i] = mul((*this)[i], g);
    return res;
  }
  poly operator-(const poly &g) const {
    poly res;
    res.resize(size());
    for (unsigned int i = 0; i < size(); i++) res[i] = sub((*this)[i], g[i]);
    return res;
  }
  inline void print() const {
    fprintf(stderr, "siz=%d :", (int)size());
    for (int x : (*this)) fprintf(stderr, "%d ", x);
    fprintf(stderr, "\n");
  }
};
inline poly calc(poly a, poly &&b) {
  for (len = 1; len < a.size() + b.size() + b.size() - 2; len <<= 1)
    ;
  for (int i = 0; i < len; i++)
    tr[i] = (tr[i >> 1] >> 1) | ((i & 1) ? (len >> 1) : 0);
  a.resize(len);
  b.resize(len);
  a.ntt();
  b.ntt();
  poly &&res = b * 2 - a * b * b;
  res.ntt(-1);
  return res;
}
inline poly inv(const poly &x) {
  if (x.size() == 1) return poly{inv(x[0])};
  poly tmp(x);
  tmp.resize((x.size() + 1) >> 1);
  tmp = calc(x, inv(tmp));
  tmp.resize(x.size());
  return tmp;
}
inline poly sqrt(const poly &x) {
  if (x.size() == 1) return poly{1};
  poly t(x);
  t.resize((x.size() + 1) >> 1);
  t = sqrt(t);
  poly g(x);
  poly inv = t * 2;
  inv.resize(x.size());
  inv = ::inv(inv);
  for (len = 1; len < t.size() + t.size() + inv.size() - 2; len <<= 1)
    ;
  for (int i = 0; i < len; i++)
    tr[i] = (tr[i >> 1] >> 1) | ((i & 1) ? (len >> 1) : 0);
  t.resize(len);
  g.resize(len);
  inv.resize(len);
  t.ntt();
  g.ntt();
  inv.ntt();
  poly res = (t * t + g) * inv;
  res.ntt(-1);
  res.resize(x.size());
  return res;
}
int main() {
  const int n = io.readi(), m = io.readi();
  poly g;
  g.resize(1e5 + 1);
  for (int i = 1; i <= n; i++) g[io.readi()] = 1;
  g.resize(m + 1);
  for (unsigned int i = 0; i < g.size(); i++) g[i] = sub(0, 4 * g[i]);
  g[0] = add(g[0], 1);
  g = sqrt(g);
  g[0] = add(g[0], 1);
  g.resize(m + 1);
  g = inv(g);
  poly f;
  f.resize(m + 1);
  f[0] = 2;
  for (int len = 1; len < g.size() + f.size() - 1; len <<= 1)
    ;
  for (int i = 0; i < len; i++)
    tr[i] = (tr[i >> 1] >> 1) | ((i & 1) ? (len >> 1) : 0);
  f.resize(len);
  g.resize(len);
  f.ntt();
  g.ntt();
  poly ans = f * g;
  ans.ntt(-1);
  for (int i = 1; i <= m; i++) io.write(ans[i], '\n');
  return 0;
}