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 optimize(3)
using namespace std;
const long long Md = 998244353, Inv2 = 499122177;
const int MAXN = (1 << 21) | 1;
int rev[MAXN], c[MAXN];
int n, m;
struct isocmplx {
  long long a, b, w;
  isocmplx(long long _a = 0, long long _b = 0, long long _w = 0)
      : a(_a), b(_b), w(_w) {}
  isocmplx operator+(const isocmplx &p) const {
    long long _a = a + p.a, _b = b + p.b;
    if (_a >= Md) _a -= Md;
    if (_b >= Md) _b -= Md;
    return isocmplx(_a, _b);
  }
  isocmplx operator-(const isocmplx &p) const {
    long long _a = a - p.a, _b = b - p.b;
    if (_a < 0) _a += Md;
    if (_b < 0) _b += Md;
    return isocmplx(_a, _b);
  }
  isocmplx operator*(const isocmplx &p) const {
    assert(w == p.w);
    long long _a = a * p.a % Md + b * p.b % Md * w % Md,
              _b = a * p.b % Md + b * p.a % Md;
    if (_a >= Md) _a -= Md;
    if (_b >= Md) _b -= Md;
    return isocmplx(_a, _b, w);
  }
};
inline long long Powe(long long x, long long y) {
  long long res = 1;
  while (y) {
    if (y & 1) res = res * x % Md;
    x = x * x % Md;
    y >>= 1;
  }
  return res;
}
inline isocmplx Powe(isocmplx x, long long y) {
  isocmplx res = isocmplx(1, 0, x.w);
  while (y) {
    if (y & 1) res = res * x;
    x = x * x;
    y >>= 1;
  }
  return res;
}
inline long long Legendre(long long p, long long q) {
  if (p < 0) p += Md;
  return Powe(p, (q - 1) >> 1);
}
inline long long Sqrt(long long x, long long Md) {
  long long res = ((rand() % Md) * (rand() % Md)) % Md;
  while (Legendre((res * res % Md - x) % Md, Md) != Md - 1) {
    res = ((rand() % Md) * (rand() % Md)) % Md;
  }
  return Powe(isocmplx(res, 1, (res * res % Md - x + Md) % Md), (Md + 1) >> 1)
      .a;
}
void Init_rev(int d, int l) {
  for (int i = 0; i < l; ++i) {
    rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (d - 1));
  }
}
void DFT(long long *A, int l) {
  for (int i = 0; i < l; ++i) {
    if (rev[i] < i) swap(A[i], A[rev[i]]);
  }
  for (int i = 2; i <= l; i <<= 1) {
    long long wn = Powe(3, (Md - 1) / i);
    int oi = i >> 1;
    for (int j = 0; j < l; j += i) {
      long long w = 1;
      for (int k = 0; k < oi; ++k) {
        long long X = A[j + k], Y = w * A[j + k + oi] % Md;
        A[j + k] = X + Y;
        if (A[j + k] >= Md) A[j + k] -= Md;
        A[j + k + oi] = X - Y;
        if (A[j + k + oi] < 0) A[j + k + oi] += Md;
        w = w * wn % Md;
      }
    }
  }
}
void IDFT(long long *A, int l) {
  reverse(A + 1, A + l);
  DFT(A, l);
  long long invl = Powe(l, Md - 2);
  for (int i = 0; i < l; ++i) {
    A[i] = A[i] * invl % Md;
  }
}
long long F[MAXN], G[MAXN], tmp[MAXN], tmp2[MAXN], tmp3[MAXN], tmp4[MAXN];
void INV(int d, long long *A, long long *B) {
  if (d == 1) {
    B[0] = Powe(A[0], Md - 2);
  } else {
    INV((d + 1) >> 1, A, B);
    int deux = ceil(log2(d << 1)), l = 1 << deux;
    copy(A, A + d, tmp);
    fill(tmp + d, tmp + l, 0);
    Init_rev(deux, l);
    DFT(tmp, l);
    DFT(B, l);
    for (int i = 0; i < l; ++i) {
      B[i] = B[i] * (2 - tmp[i] * B[i] % Md) % Md;
      if (B[i] < 0) B[i] += Md;
    }
    IDFT(B, l);
    fill(B + d, B + l, 0);
  }
}
void SQRT(int d, long long *A, long long *B) {
  if (d == 1) {
    B[0] = Sqrt(A[0], Md);
  } else {
    SQRT((d + 1) >> 1, A, B);
    int deux = ceil(log2(d << 1)), l = 1 << deux;
    copy(A, A + d, tmp3);
    fill(tmp3 + d, tmp3 + l, 0);
    copy(B, B + d, tmp4);
    memset(tmp2, 0, sizeof tmp2);
    INV(d, B, tmp2);
    fill(tmp2 + d, tmp2 + l, 0);
    Init_rev(deux, l);
    DFT(tmp3, l);
    DFT(tmp2, l);
    DFT(B, l);
    for (int i = 0; i < l; ++i) {
      B[i] = B[i] + tmp3[i] * tmp2[i] % Md;
      if (B[i] >= Md) B[i] -= Md;
    }
    IDFT(B, l);
    for (int i = 0; i < d; ++i) {
      B[i] = B[i] * Inv2 % Md;
    }
    fill(B + d, B + l, 0);
  }
}
int main() {
  srand(time(0));
  memset(F, 0, sizeof F);
  memset(G, 0, sizeof G);
  scanf("%d%d", &n, &m);
  ++m;
  for (int i = 0; i < n; ++i) {
    scanf("%d", &c[i]);
    if (c[i] <= m) F[c[i]] = 1;
  }
  int deux = ceil(log2(m << 1)), l = 1 << deux;
  for (int i = 0; i < l; ++i) {
    F[i] = -(F[i] << 2) % Md;
    if (F[i] < 0) F[i] += Md;
  }
  F[0]++;
  if (F[0] >= Md) F[0] -= Md;
  SQRT(m, F, G);
  G[0]++;
  if (G[0] >= Md) G[0] -= Md;
  memset(F, 0, sizeof F);
  INV(m, G, F);
  int fl = 0;
  for (int i = 1; i < m; ++i) {
    F[i] = F[i] * 2 % Md;
    if (F[i] == 0) ++fl;
  }
  if (fl == m - 1) {
    G[0] -= 2;
    if (G[0] < 0) G[0] += Md;
    memset(F, 0, sizeof F);
    INV(m, G, F);
    for (int i = 1; i < m; ++i) {
      F[i] = -F[i] * 2 % Md;
      if (F[i] < 0) F[i] += Md;
    }
  }
  for (int i = 1; i < m; ++i) {
    printf("%lld\n", F[i]);
  }
  return 0;
}