// clang-format off #include #include #include #define mp make_pair #define fst first #define snd second #define forn(i,n) for (int i = 0; i < int(n); i++) #define forn1(i,n) for (int i = 1; i <= int(n); i++) #define popcnt __builtin_popcountll #define ffs __builtin_ffsll #define ctz __builtin_ctzll #define clz __builtin_clz #define clzll __builtin_clzll #define all(a) (a).begin(), (a).end() using namespace std; using namespace __gnu_pbds; using uint = unsigned int; using ll = long long; using ull = unsigned long long; using pii = pair; using pli = pair; using pil = pair; using pll = pair; template using vec = vector; using vi = vec; using vl = vec; template using que = queue; template using deq = deque; template using ordered_set = tree, rb_tree_tag, tree_order_statistics_node_update>; template using ordered_map = tree, rb_tree_tag, tree_order_statistics_node_update>; template T id(T b) {return b;}; template void chmax(T &x, T y) {if (x < y) x = y;} template void chmin(T &x, T y) {if (x > y) x = y;} template bool contains(S &s, K k) { return s.find(k) != s.end(); } template bool getf(T flag, size_t i) { return (flag>>i) & 1; } template T setf(T flag, size_t i) { return flag | (T(1)< T unsetf(T flag, size_t i) { return flag & ~(T(1)< long long mod_pow(long long a, long long b) { if (b == 0) return 1; long long ret = mod_pow(a, b / 2); ret = ret * ret % mod; if (b % 2 == 1) ret = a * ret % mod; return ret; } template struct Comb { int n; vector fact, inv; Comb(int n) : n(n), fact(n + 1, 0), inv(n + 1, 0) { assert(n < mod); fact[0] = 1; for (int i = 1; i <= n; i++) fact[i] = fact[i - 1] * i % mod; inv[n] = mod_pow(fact[n], mod - 2); for (int i = n; i >= 1; i--) inv[i - 1] = inv[i] * i % mod; } long long operator()(int m, int k) { assert(!(m > n || m < k || k < 0)); return fact[m] * inv[m - k] % mod * inv[k] % mod; } }; const ll MOD = 998244353; int main() { fastio(); int n, l; cin >> n >> l; vi a(n); forn(i, n) cin >> a[i]; Comb comb(n + 1); vec ans(n); auto calc = [&](bool b) { // iが最後に右から落ちるような場合の数 for (int i = n - 1; i >= 0; i--) { int d = l - a[i]; // 右端までの距離 int k; // iより右側にある要素のうち、左端までの距離が(dより大きい)or(d以上)のもの最左の位置 bool ok; // 左隣の要素の左端までの距離が(d以上)or(dより大きい)かをチェック if (b) { k = upper_bound(all(a), d) - a.begin(); ok = i == 0 or a[i - 1] <= d; } else { k = lower_bound(all(a), d) - a.begin(); ok = i == 0 or a[i - 1] < d; } k = max(k, i + 1); // iより右にある要素のうち、自由に向きを選んで良い(左向きでも良い)ものの数 int c = k - i - 1; if (ok) { // j: 左向きのものの数 for (int j = 0; j <= c; j++) { // 右向きのものの数 int x = n - i - j; ans[n - x] = (ans[n - x] + comb(c, j)) % MOD; } } } }; calc(false); for (auto& x : a) x = l - x; reverse(all(a)); reverse(all(ans)); calc(true); reverse(all(ans)); for (auto x : ans) { cout << x << "\n"; } return 0; }