#include #define rep(i,s,n) for (int i = (int)(s); i < (int)(n); i++) #define all(v) begin(v),end(v) using namespace std; using ll = long long; bool chmin(auto &a, auto b){ return a > b ? a = b, 1 : 0; } bool chmax(auto &a, auto b){ return a < b ? a = b, 1 : 0; } template ostream &operator<<(ostream &os, const vector &a){ rep(i, 0, a.size()) os << (i ? " " : "") << a[i]; return os; } void dump(auto ...vs){ ((cerr << vs << ' '), ...) << endl; } struct PermutationTree { enum Type { Prime, Inc, Dec, Leaf }; struct Node { int parent; Type type; int l, r; }; vector tree; PermutationTree(vector p) { int n = p.size(); vector q(n); rep(i, 0, n) q[p[i]] = i; vector> mn(bit_width((unsigned)n), q); rep(k, 1, mn.size()) rep(i, 0, n - (1 << k) + 1) mn[k][i] = min(mn[k - 1][i], mn[k - 1][i + (1 << (k - 1))]); auto rmq = [&](int l, int r) { int k = bit_width((unsigned)(r - l)) - 1; return min(mn[k][l], mn[k][r - (1 << k)]); }; struct Base { int l, lo, hi; }; vector st; vector> coms; rep(r, 1, n + 1) { Base b{r - 1, p[r - 1], p[r - 1] + 1}; while(st.size()) { st.back().lo = min(st.back().lo, b.lo); st.back().hi = max(st.back().hi, b.hi); auto x = st.back(); if(rmq(x.lo, x.hi) < x.l) { st.pop_back(); st.back().lo = min(st.back().lo, x.lo); st.back().hi = max(st.back().hi, x.hi); } else if(x.hi - x.lo == r - x.l) { b = x; st.pop_back(); coms.emplace_back(x.l, r); } else break; } st.push_back(b); } while(st.size() > 1) { auto x = st.back(); st.pop_back(); auto& y = st.back(); y.lo = min(y.lo, x.lo); y.hi = max(y.hi, x.hi); if(y.hi - y.lo == n - y.l) coms.emplace_back(y.l, n); } if(st.size() != 1) coms.emplace_back(0, n); rep(i, 0, n) tree.push_back({-1, Leaf, i, i + 1}); vector id(n), nxt(n); iota(all(id), 0); rep(i, 0, n) nxt[i] = i + 1; for(auto [l, r] : coms) { int m = nxt[l]; if(nxt[m] == r) { int a = id[l], b = id[m]; nxt[l] = r; Type t = p[l] < p[r - 1] ? Inc : Dec; if(tree[a].type == t) { tree[b].parent = a; tree[a].r = r; } else { int c = tree.size(); tree.push_back({-1, t, l, r}); tree[a].parent = tree[b].parent = c; id[l] = c; } } else { int c = tree.size(); tree.push_back({-1, Prime, l, r}); for(int i = l; i < r; i = nxt[i]) tree[id[i]].parent = c; id[l] = c; nxt[l] = r; } } } }; template struct mm { uint32_t x; mm() : x(0) {} template mm(T a) : x(a % m) { if(x >= m) x += m; // x is unsigned, (x < 0) <=> (x >= mod) } template mm(T a) : x(a % m) {} friend mm operator+(mm a, mm b) { a.x += b.x; if(a.x >= m) a.x -= m; return a; } friend mm operator-(mm a, mm b) { a.x -= b.x; if(a.x >= m) a.x += m; // a.x < 0, a.x [[+=]] m return a; } friend mm operator*(mm a, mm b) { return (uint64_t)a.x * b.x; } mm pow(ll n) const { mm a = *this, ret = 1; while(n) { if(n & 1) ret *= a; a *= a; n >>= 1; } return ret; } mm inv() const { return pow(m - 2); } friend mm operator/(mm a, mm b) { return a * b.inv(); } mm operator-() const { return mm(0) - *this; } bool operator==(mm b) const { return x == b.x; } friend mm& operator+=(mm& a, mm b) { return a = a + b; } friend mm& operator-=(mm& a, mm b) { return a = a - b; } friend mm& operator*=(mm& a, mm b) { return a = a * b; } friend mm& operator/=(mm& a, mm b) { return a = a * b.inv(); } static int mod() { return m; } friend ostream &operator<<(ostream &os, const mm &a){ return os << a.x; } }; using mint = mm<998244353>; void solve(){ int n, k; cin >> n >> k; vector p(n); rep(i,0,n){ cin >> p[i]; --p[i]; } PermutationTree pt(p); auto nodes = pt.tree; int sz = nodes.size(); vector> g(sz); int root = -1; rep(i,0,sz){ int par = nodes[i].parent; if (par != -1){ g[par].emplace_back(i); } else { root = i; } } rep(i,0,sz){ ranges::sort(g[i],{},[&](int v){ return nodes[v].l; }); } using ar = array; using PT = PermutationTree; auto dfs = [&](auto sfs, int v) -> ar { if (nodes[v].type == PT::Leaf){ ar dp = {}; dp[1] = 1; return dp; } if (nodes[v].type == PT::Prime){ ar dp = {}; dp[0] = 1; for (int u : g[v]){ auto ep = sfs(sfs,u); ar ndp = {}; rep(i,0,k) rep(j,1,k+1-i){ ndp[i+j] += dp[i] * ep[j]; } swap(dp,ndp); } dp[1] += 1; return dp; } ar dp = {}; dp[0] = 1; ar rui = {}; for (int u : g[v]){ auto ep = sfs(sfs,u); ar ndp = {}; rep(i,0,k) rep(j,1,k+1-i){ ndp[i+j] += dp[i] * ep[j]; } rep(i,0,k){ ndp[i+1] += rui[i]; } rep(i,0,k+1){ rui[i] += dp[i]; } swap(dp,ndp); } // dump(nodes[v].l,nodes[v].r,":",ranges::to>(dp)); return dp; }; auto dp = dfs(dfs,root); rep(i,1,k+1){ cout << dp[i].x << '\n'; } } int main(){ cin.tie(0)->sync_with_stdio(0); solve(); }