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;
template <class T>
inline void upmax(T &a, T b) {
  if (a < b) a = b;
}
template <class T>
inline void upmin(T &a, T b) {
  if (a > b) a = b;
}
const int maxn = 524288;
const int maxm = 200007;
const int mod = 998244353;
const int inf = 0x7fffffff;
const int G = 3;
typedef int arr[maxn];
typedef int adj[maxm];
inline int add(int a, int b) { return ((long long)a + b) % mod; }
inline int mul(int a, int b) { return ((long long)a * b) % mod; }
inline int dec(int a, int b) { return add(a, mod - b % mod); }
inline int Pow(int a, int b) {
  int t = 1;
  while (b) {
    if (b & 1) t = mul(t, a);
    a = mul(a, a), b >>= 1;
  }
  return t;
}
template <typename Type>
inline Type RD() {
  char c = getchar();
  Type x = 0, flag = 1;
  while (!isdigit(c) && c != '-') c = getchar();
  if (c == '-')
    flag = -1;
  else
    x = c - '0';
  while (isdigit(c = getchar())) x = x * 10 + c - '0';
  return x * flag;
}
inline char rdch() {
  char c = getchar();
  while (!isalpha(c)) c = getchar();
  return c;
}
int n, m, inv2;
arr C;
void input() {
  n = RD<int>(), m = RD<int>();
  C[0] = 1;
  for (int i = 1, _ = n; i <= _; i++) {
    int x = RD<int>();
    C[x] = dec(C[x], 4);
  }
  inv2 = Pow(2, mod - 2);
}
int N, len;
arr rev, wn;
inline void init(int n, int m) {
  for (N = 1, len = 0; N <= n + m; N <<= 1, len++)
    ;
  for (int i = 1, _ = N; i < _; i++)
    rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (len - 1));
  wn[0] = 1;
  int g = Pow(G, (mod - 1) / N);
  for (int i = 1, _ = N; i < _; i++) wn[i] = mul(wn[i - 1], g);
}
inline void fft(int *a, int n) {
  for (int i = 1, _ = n; i < _; i++)
    if (i < rev[i]) swap(a[i], a[rev[i]]);
  for (int s = 2, i = 1; s <= n; s <<= 1, i++) {
    int wm = wn[1 << (len - i)];
    for (int k = 0; k < n; k += s) {
      int w = 1;
      for (int j = 0, _ = s / 2; j < _; j++) {
        int u = a[k + j], t = mul(w, a[k + j + s / 2]);
        a[k + j] = add(u, t), a[k + j + s / 2] = dec(u, t);
        w = mul(w, wm);
      }
    }
  }
}
inline void dft(int *a) { fft(a, N); }
inline void idft(int *a, int rev = 1) {
  if (rev) reverse(wn + 1, wn + N);
  fft(a, N);
  int invN = Pow(N, mod - 2);
  for (int i = 0, _ = N; i < _; i++) a[i] = mul(a[i], invN);
}
static arr sqrt_C, inv_sqrt_C;
inline void getPolyInv(int *A, int *B, int n) {
  static arr tmp;
  fill(tmp, tmp + n, 0);
  B[0] = Pow(A[0], mod - 2), B[1] = 0;
  for (int s = 2; s <= n; s <<= 1) {
    init(s, s);
    for (int i = 0, _ = s; i < _; i++) tmp[i] = A[i];
    dft(B), dft(tmp);
    for (int i = 0, _ = N; i < _; i++)
      B[i] = mul(B[i], dec(2, mul(tmp[i], B[i])));
    idft(B);
    fill(B + s, B + N, 0);
    fill(tmp, tmp + N, 0);
  }
}
inline void getPolySqrt(int *A, int *B, int n) {
  static arr tmp, invB;
  fill(tmp, tmp + n, 0);
  fill(invB, invB + n, 0);
  B[0] = 1, B[1] = 0;
  for (int s = 2; s <= n; s <<= 1) {
    getPolyInv(B, invB, s);
    init(s, s);
    for (int i = 0, _ = s; i < _; i++) tmp[i] = A[i];
    dft(tmp), dft(invB), dft(B);
    for (int i = 0, _ = N; i < _; i++)
      B[i] = mul(inv2, add(B[i], mul(tmp[i], invB[i])));
    idft(B);
    fill(B + s, B + N, 0);
    fill(tmp, tmp + N, 0);
    fill(invB, invB + N, 0);
  }
}
void solve() {
  int N = 1;
  while (N <= m) N <<= 1;
  getPolySqrt(C, sqrt_C, N);
  sqrt_C[0]++;
  getPolyInv(sqrt_C, inv_sqrt_C, N);
  for (int i = 1, _ = m; i <= _; i++) printf("%d\n", mul(inv_sqrt_C[i], 2));
}
int main() {
  input();
  solve();
  return 0;
}