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>
namespace test {
typedef unsigned int *ptr_t;
static const unsigned int BUFFER_SIZE = 1U << 21U;
typedef unsigned int arr_t[BUFFER_SIZE];
static constexpr unsigned int P = 998244353U, G = 3U;
static arr_t ROOT;
unsigned int get_len(unsigned int n) {
  unsigned int len = 1;
  while (len < n) len <<= 1U;
  return len;
}
unsigned int mod_pow(unsigned int x, unsigned int exp) {
  unsigned int res = 1;
  for (; exp != 0;
       exp >>= 1U, x = static_cast<unsigned long long int>(x) * x % P)
    if (exp & 1U) res = static_cast<unsigned long long int>(res) * x % P;
  return res;
}
unsigned int mod_inv(unsigned int x) { return mod_pow(x, P - 2); }
unsigned int legendre_symbol(unsigned int x) {
  return x == 0 ? 0 : mod_pow(x, P - 1 >> 1);
}
unsigned int tonelli_shanks(unsigned int a) {
  if (legendre_symbol(a) != 1) return 0;
  unsigned int q = P - 1, t = 0, n, z;
  while (!(q & 1U)) q >>= 1U, ++t;
  if (t == 1) return mod_pow(a, P + 1 >> 2U);
  for (n = 1; n != P; ++n)
    if (legendre_symbol(n) == P - 1) {
      z = mod_pow(n, q);
      break;
    }
  unsigned int y = z, r = t, x = mod_pow(a, q - 1 >> 1U), b = x;
  x = static_cast<unsigned long long int>(x) * a % P,
  b = static_cast<unsigned long long int>(x) * b % P;
  while (true) {
    if (b == 1) return x < P - x ? x : P - x;
    unsigned int m = 1;
    for (; m < r; ++m)
      if (mod_pow(b, 1U << m) == 1) break;
    unsigned int v = mod_pow(y, 1U << r - m - 1);
    y = static_cast<unsigned long long int>(v) * v % P, r = m,
    x = static_cast<unsigned long long int>(x) * v % P,
    b = static_cast<unsigned long long int>(b) * y % P;
  }
}
void revbin(unsigned int n, ptr_t x) {
  for (unsigned int i = 0, j = 0; i != n; ++i) {
    if (i < j) {
      unsigned int t = *(x + i);
      *(x + i) = *(x + j), *(x + j) = t;
    }
    for (unsigned int k = n >> 1U; (j ^= k) < k; k >>= 1U) {
    }
  }
}
void reverse(ptr_t x, ptr_t y) {
  unsigned int t;
  while (y - x > 0) t = *x, *x++ = *--y, *y = t;
}
void dif_ntt_core(unsigned int n, ptr_t x) {
  for (unsigned int i = n; i != 1; i >>= 1U)
    for (unsigned int j = 0, l = i >> 1U; j != n; j += i)
      for (unsigned int k = 0; k != l; ++k) {
        unsigned int u = *(x + j + k), v = *(x + j + k + l);
        *(x + j + k) = (u + v) % P,
                  *(x + j + k + l) =
                      (static_cast<unsigned long long int>(u) + P - v) *
                      ROOT[l + k] % P;
      }
}
void dit_ntt_core(unsigned int n, ptr_t x) {
  for (unsigned int i = 2; i <= n; i <<= 1U)
    for (unsigned int j = 0, l = i >> 1U; j != n; j += i)
      for (unsigned int k = 0; k != l; ++k) {
        unsigned int u = *(x + j + k),
                     v = static_cast<unsigned long long int>(ROOT[l + k]) *
                         *(x + j + k + l) % P;
        *(x + j + k) = (u + v) % P, *(x + j + k + l) = (u + P - v) % P;
      }
}
void inplace_dft(unsigned int n, ptr_t x) {
  static unsigned int lim = 1;
  if (lim < n) {
    unsigned int l = n >> 1U;
    unsigned int g = mod_pow(G, (P - 1) / n);
    ROOT[l] = 1;
    for (unsigned int i = l + 1; i < n; ++i)
      ROOT[i] = static_cast<unsigned long long int>(ROOT[i - 1]) * g % P;
    for (unsigned int i = l - 1; i >= lim; --i) ROOT[i] = ROOT[i << 1U];
    lim = n;
  }
  dif_ntt_core(n, x);
}
void inplace_idft(unsigned int n, ptr_t x) {
  dit_ntt_core(n, x), reverse(x + 1, x + n);
  unsigned int in = P - (P - 1) / n;
  for (ptr_t i = x, e = x + n; i != e; ++i)
    *i = static_cast<unsigned long long int>(*i) * in % P;
}
struct Poly {
 private:
  ptr_t first, last, end_of_storage;

 public:
  typedef unsigned int const *const_iterator;
  ptr_t begin() { return first; }
  ptr_t end() { return last; }
  const_iterator begin() const { return first; }
  const_iterator end() const { return last; }
  unsigned int size() const { return last - first; }
  unsigned int capacity() const { return end_of_storage - first; }
  bool empty() const { return first == last; }
  unsigned int &operator[](unsigned int x) { return *(first + x); }
  unsigned int operator[](unsigned int x) const { return *(first + x); }
  Poly &resize(unsigned int new_size) {
    if (new_size > capacity()) {
      unsigned int old_capacity = capacity(), new_capacity = get_len(new_size);
      first = static_cast<ptr_t>(
          realloc(first, sizeof(unsigned int) * new_capacity));
      assert(first != nullptr);
      end_of_storage = first + new_capacity;
      memset(first + old_capacity, 0,
             sizeof(unsigned int) * (new_capacity - old_capacity));
    } else if (size() > new_size)
      memset(first + new_size, 0, sizeof(unsigned int) * (size() - new_size));
    return last = first + new_size, *this;
  }
  explicit Poly(unsigned int reserved = 1)
      : first(static_cast<ptr_t>(
            calloc(get_len(reserved), sizeof(unsigned int)))),
        last(first + reserved),
        end_of_storage(first + get_len(reserved)) {
    assert(reserved > 0 && first != nullptr);
  }
  Poly(const_iterator start, const_iterator finish)
      : first(static_cast<ptr_t>(
            malloc(get_len(finish - start) * sizeof(unsigned int)))),
        last(first + (finish - start)),
        end_of_storage(first + get_len(finish - start)) {
    assert(first != nullptr);
    memcpy(first, start, sizeof(unsigned int) * (finish - start));
    memset(last, 0, sizeof(unsigned int) * (end_of_storage - last));
  }
  Poly(const Poly &rhs) : Poly(rhs.first, rhs.last) {}
  Poly(std::initializer_list<unsigned int> l) : Poly(l.begin(), l.end()) {}
  ~Poly() { free(first); }
  Poly copy() const { return Poly(*this); }
  Poly slice(unsigned int len) const { return Poly(first, first + len); }
  Poly &dft(unsigned int len) {
    return resize(len), inplace_dft(len, first), *this;
  }
  Poly &idft(unsigned int len) {
    return resize(len), inplace_idft(len, first), *this;
  }
  Poly &operator=(const Poly &rhs) {
    return resize(rhs.size()),
           memcpy(first, rhs.first, sizeof(unsigned int) * rhs.size()), *this;
  }
  Poly operator-() const {
    Poly res(*this);
    for (ptr_t i = res.first; i != res.last; ++i)
      if (*i != 0) *i = P - *i;
    return res;
  }
  Poly &operator+=(const Poly &rhs) {
    if (size() < rhs.size()) resize(rhs.size());
    for (unsigned int i = 0, len = rhs.size(); i != len; ++i)
      *(first + i) = (*(first + i) + *(rhs.first + i)) % P;
    return *this;
  }
  Poly &operator-=(const Poly &rhs) {
    if (size() < rhs.size()) resize(rhs.size());
    for (unsigned int i = 0, len = rhs.size(); i != len; ++i)
      *(first + i) = (*(first + i) + P - *(rhs.first + i)) % P;
    return *this;
  }
  Poly &operator*=(const Poly &rhs) {
    static const unsigned int THRESHOLD = 128;
    unsigned int n = size(), m = rhs.size(), len = get_len(n + m - 1);
    if (n + m - 1 <= THRESHOLD) {
      Poly res(n + m - 1);
      for (unsigned int i = 0; i != n; ++i)
        for (unsigned int j = 0; j != m; ++j)
          *(res.first + i + j) =
              (*(res.first + i + j) +
               static_cast<unsigned long long int>(*(first + i)) *
                   *(rhs.first + j)) %
              P;
      return *this = res;
    }
    Poly rhs_cpy(rhs);
    dft(len), rhs_cpy.dft(len);
    for (unsigned int i = 0; i != len; ++i)
      *(first + i) = (static_cast<unsigned long long int>(*(first + i)) *
                      *(rhs_cpy.first + i)) %
                     P;
    return idft(len).resize(n + m - 1);
  }
  Poly &operator/=(const Poly &rhs) {
    if (size() < rhs.size()) return *this = Poly{0};
    unsigned int n = size() - rhs.size() + 1;
    Poly rhs_cpy(rhs);
    reverse(first, last), reverse(rhs_cpy.first, rhs_cpy.last);
    return (*this *= rhs_cpy.resize(n).inv()).resize(n), reverse(first, last),
           *this;
  }
  Poly &operator%=(const Poly &rhs) {
    return size() >= rhs.size()
               ? (*this -= (*this / rhs) * rhs).resize(rhs.size() - 1)
               : *this;
  }
  Poly &inplace_deriv() {
    assert(size() >= 2);
    for (unsigned int i = 1, len = size(); i < len; ++i)
      *(first + i - 1) =
          static_cast<unsigned long long int>(*(first + i)) * i % P;
    return *(--last) = 0, *this;
  }
  Poly &inplace_integr() {
    static unsigned int lim = 0;
    static arr_t INV;
    unsigned int n = size();
    if (lim < n) {
      INV[1] = 1;
      for (unsigned int i = (lim < 2 ? 2 : lim); i < n; ++i)
        INV[i] =
            static_cast<unsigned long long int>(P - P / i) * INV[P % i] % P;
    }
    for (unsigned int i = size() - 1; i > 0; --i)
      *(first + i) =
          static_cast<unsigned long long int>(*(first + i - 1)) * INV[i] % P;
    return *first = 0, *this;
  }
  Poly deriv() const { return copy().inplace_deriv(); }
  Poly integr() const { return copy().inplace_integr(); }
  Poly inv() const {
    assert(*first != 0);
    unsigned int n = size(), len = get_len(n);
    Poly res(len << 1U);
    res[0] = mod_inv(*first);
    for (unsigned int i = 2; i <= len; i <<= 1U) {
      Poly cpy(begin(), begin() + i), res_cpy(res);
      res_cpy.dft(i), cpy.dft(i);
      for (unsigned int j = 0; j != i; ++j)
        *(cpy.first + j) =
            static_cast<unsigned long long int>(*(cpy.first + j)) *
            *(res_cpy.first + j) % P;
      cpy.idft(i);
      std::memset(cpy.begin(), 0, sizeof(unsigned int) * (i >> 1));
      cpy.dft(i);
      for (unsigned int j = 0; j != i; ++j)
        *(cpy.first + j) =
            static_cast<unsigned long long int>(*(cpy.first + j)) *
            *(res_cpy.first + j) % P;
      cpy.idft(i), res.resize(i);
      for (ptr_t j = cpy.begin() + (i >> 1), e = cpy.end(); j != e; ++j)
        if (*j != 0) *j = P - *j;
      std::memcpy(res.begin() + (i >> 1), cpy.begin() + (i >> 1),
                  sizeof(unsigned int) * (i >> 1));
    }
    return res.resize(n);
  }
  Poly log() const {
    assert(*first == 1);
    return (deriv() * inv()).resize(size()).inplace_integr();
  }
  Poly exp() const {
    assert(*first == 0);
    unsigned int n = size(), len = get_len(n);
    Poly res(len << 1U);
    res[0] = 1;
    for (unsigned int i = 2; i <= len; i <<= 1U)
      res *= slice(i) - res.resize(i).log() + Poly{1};
    return res.resize(n);
  }
  Poly isqrt() const {
    assert(legendre_symbol(*first) == 1);
    unsigned int n = size(), len = get_len(n);
    Poly res(len << 1U);
    res[0] = mod_inv(tonelli_shanks(*first));
    unsigned int inv2 = (P >> 1U) + 1;
    for (unsigned int i = 2; i <= len; i <<= 1U) {
      Poly t = Poly{1} - ((slice(i) * res.resize(i)).resize(i) * res).resize(i);
      for (ptr_t j = t.first; j != t.last; ++j)
        *j = static_cast<unsigned long long int>(*j) * inv2 % P;
      res += (res * t).resize(i);
    }
    return res.resize(n);
  }
  Poly sqrt() const { return (*this * isqrt()).resize(size()); }
  Poly pow(unsigned int k1, unsigned int k2 = 0) const {
    if (*first == 1) {
      Poly res = log();
      for (ptr_t i = res.first; i != res.last; ++i)
        *i = static_cast<unsigned long long int>(*i) * k1 % P;
      return res.exp();
    } else {
      Poly res(size());
      ptr_t not0_pos = first;
      for (; not0_pos != last; ++not0_pos)
        if (*not0_pos != 0) {
          res = Poly(not0_pos, last);
          break;
        }
      if (not0_pos == last ||
          static_cast<unsigned long long int>(k1) * (not0_pos - first) >=
              size())
        return Poly(size());
      unsigned int res0 = res[0], res0_inv = mod_inv(res0);
      for (ptr_t i = res.first; i != res.last; ++i)
        *i = static_cast<unsigned long long int>(*i) * res0_inv % P;
      res = res.log();
      for (ptr_t i = res.first; i != res.last; ++i)
        *i = static_cast<unsigned long long int>(*i) * k1 % P;
      res = res.exp();
      res0 = mod_pow(res0, k2 == 0 ? k1 : k2);
      for (ptr_t i = res.first; i != res.last; ++i)
        *i = static_cast<unsigned long long int>(*i) * res0 % P;
      res.resize(size());
      memmove(res.first + k1 * (not0_pos - first), res.first,
              sizeof(unsigned int) * (res.size() - k1 * (not0_pos - first)));
      memset(res.first, 0, sizeof(unsigned int) * k1 * (not0_pos - first));
      return res;
    }
  }
  Poly chirpz(unsigned int z, unsigned int n) const;
  unsigned int horner(unsigned int x) const {
    unsigned int res = *(last - 1);
    for (ptr_t i = last - 1; i != first; --i)
      res = (static_cast<unsigned long long int>(res) * x + *(i - 1)) % P;
    return res;
  }
  static void segment_tree_build(
      std::vector<Poly> &vp, unsigned int pos,
      std::vector<unsigned int>::const_iterator start,
      std::vector<unsigned int>::const_iterator finish) {
    if (finish - start == 1)
      vp[pos] = Poly{P - *start, 1};
    else {
      std::vector<unsigned int>::const_iterator mid =
          start + (finish - start >> 1U);
      segment_tree_build(vp, pos << 1U, start, mid),
          segment_tree_build(vp, pos << 1U | 1U, mid, finish);
      vp[pos] = vp[pos << 1U] * vp[pos << 1U | 1U];
    }
  }
  static void segment_tree_solve(
      std::vector<Poly> &vp, unsigned int pos,
      std::vector<unsigned int>::const_iterator start,
      std::vector<unsigned int>::const_iterator finish, const Poly &r,
      std::vector<unsigned int> &res) {
    static const unsigned int THRESHOLD = 128;
    if (finish - start <= THRESHOLD) {
      for (std::vector<unsigned int>::const_iterator it = start; it != finish;
           ++it)
        res.push_back(r.horner(*it));
      return;
    } else {
      std::vector<unsigned int>::const_iterator mid =
          start + (finish - start >> 1U);
      segment_tree_solve(vp, pos << 1U, start, mid, r % vp[pos << 1U], res),
          segment_tree_solve(vp, pos << 1U | 1U, mid, finish,
                             r % vp[pos << 1U | 1U], res);
    }
  }
  std::vector<unsigned int> eval(
      const std::vector<unsigned int> &points) const {
    std::vector<Poly> vp(points.size() << 2U);
    segment_tree_build(vp, 1, points.begin(), points.end());
    std::vector<unsigned int> res;
    segment_tree_solve(vp, 1, points.begin(), points.end(), *this % vp[1], res);
    return res;
  }
  static Poly inter_rec(const std::vector<Poly> &vp, unsigned int pos,
                        std::vector<unsigned int>::const_iterator start,
                        std::vector<unsigned int>::const_iterator finish) {
    if (finish - start == 1)
      return Poly{*start};
    else {
      std::vector<unsigned int>::const_iterator mid =
          start + (finish - start >> 1U);
      return inter_rec(vp, pos << 1U, start, mid) * vp[pos << 1U | 1U] +
             inter_rec(vp, pos << 1U | 1U, mid, finish) * vp[pos << 1U];
    }
  }
  static Poly inter(const std::vector<unsigned int> &x,
                    const std::vector<unsigned int> &y) {
    unsigned int n = x.size();
    assert(y.size() == n);
    std::vector<Poly> vp(n << 2U);
    segment_tree_build(vp, 1, x.begin(), x.end());
    std::vector<unsigned int> v;
    segment_tree_solve(vp, 1, x.begin(), x.end(), vp[1].deriv() % vp[1], v);
    for (unsigned int i = 0; i != n; ++i)
      v[i] = mod_inv(v[i]) * static_cast<unsigned long long int>(y[i]) % P;
    return inter_rec(vp, 1, v.begin(), v.end());
  }
  friend Poly operator+(const Poly &lhs, const Poly &rhs) {
    return Poly(lhs) += rhs;
  }
  friend Poly operator-(const Poly &lhs, const Poly &rhs) {
    return Poly(lhs) -= rhs;
  }
  friend Poly operator*(const Poly &lhs, const Poly &rhs) {
    return Poly(lhs) *= rhs;
  }
  friend Poly operator/(const Poly &lhs, const Poly &rhs) {
    return Poly(lhs) /= rhs;
  }
  friend Poly operator%(const Poly &lhs, const Poly &rhs) {
    return Poly(lhs) %= rhs;
  }
};
}  // namespace test
using test::Poly;
using namespace std;
using ll = long long;
using ull = unsigned long long;
const int N = 2e5 + 5;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  int t;
  Poly a(m + 1);
  for (int i = 0; i < n; ++i) {
    cin >> t;
    if (t <= m) a[t] = 1;
  }
  Poly ans = Poly{2} * (Poly{1} + (Poly{1} - Poly{4} * a).sqrt()).inv();
  for (int i = 1; i != m + 1; ++i) cout << ans[i] << '\n';
  return 0;
}