#include using namespace std; using ll=long long; using ull=unsigned long long; using P=pair; templateusing minque=priority_queue,greater>; templatebool chmax(T &a,const T &b){return (abool chmin(T &a,const T &b){return (a>b?(a=b,true):false);} templateistream &operator>>(istream &is,pair&p){is>>p.first>>p.second;return is;} templateistream &operator>>(istream &is,tuple&a){is>>std::get<0>(a)>>std::get<1>(a)>>std::get<2>(a);return is;} templateistream &operator>>(istream &is,array&a){for(auto&i:a)is>>i;return is;} templateistream &operator>>(istream &is,vector &a){for(auto &i:a)is>>i;return is;} templatevoid operator++(pair&a,int n){a.first++,a.second++;} templatevoid operator--(pair&a,int n){a.first--,a.second--;} templatevoid operator++(vector&a,int n){for(auto &i:a)i++;} templatevoid operator--(vector&a,int n){for(auto &i:a)i--;} #define overload3(_1,_2,_3,name,...) name #define rep1(i,n) for(int i=0;i<(int)(n);i++) #define rep2(i,l,r) for(int i=(int)(l);i<(int)(r);i++) #define rep(...) overload3(__VA_ARGS__,rep2,rep1)(__VA_ARGS__) #define reps(i,l,r) rep2(i,l,r) #define all(x) x.begin(),x.end() #define pcnt(x) __builtin_popcountll(x) #define fin(x) return cout<<(x)<<'\n',static_cast(0) #define yn(x) cout<<((x)?"Yes\n":"No\n") #define uniq(x) sort(all(x)),x.erase(unique(all(x)),x.end()) template inline int fkey(vector&z,T key){return lower_bound(z.begin(),z.end(),key)-z.begin();} ll myceil(ll a,ll b){return (a+b-1)/b;} template auto vec(const int (&d)[n],const T &init=T()){ if constexpr (id(d,init)); else return init; } #ifdef LOCAL #include #define SWITCH(a,b) (a) #else #define debug(...) static_cast(0) #define debugg(...) static_cast(0) #define SWITCH(a,b) (b) templateostream &operator<<(ostream &os,const pair&p){os<>testcase; for(int i=0;i #include template constexpr std::enable_if_t::digits<=32,int>msb(T n){return n==0?-1:31-__builtin_clz(n);} template constexpr std::enable_if_t<(std::numeric_limits::digits>32),int>msb(T n){return n==0?-1:63-__builtin_clzll(n);} template constexpr std::enable_if_t::digits<=32,int>lsb(T n){return n==0?-1:__builtin_ctz(n);} template constexpr std::enable_if_t<(std::numeric_limits::digits>32),int>lsb(T n){return n==0?-1:__builtin_ctzll(n);} template constexpr std::enable_if_t,T>floor_pow2(T n){return n==0?0:T(1)< constexpr std::enable_if_t,T>ceil_pow2(T n){return n<=1?1:T(1)<<(msb(n-1)+1);} template constexpr T safe_div(T a,T b){return a>=0?a/b:-((-a+b-1)/b);} template struct LazySegmentTree{ private: using S=typename M::S; using F=typename M::F; int n,z; int log2n; std::vectordat; std::vectorlazy; inline void propagate(int i,const F&f){ dat[i]=M::mapping(f,dat[i],1<<(log2n-msb(i))); lazy[i]=M::composition(f,lazy[i]); } inline void push(int i){ if(il;j--)push(i>>j); } inline void path_update(int i){ int l=lsb(i); i>>=(l+1); while(i){ update(i); i>>=1; } } public: LazySegmentTree():n(0),z(0),log2n(0){} explicit LazySegmentTree(int n_):n(n_),z(ceil_pow2(n_)){ log2n=msb(z); dat.resize(z*2,M::e()),lazy.resize(z*2,M::id()); } explicit LazySegmentTree(const std::vector&init):n(init.size()),z(ceil_pow2((int)init.size())){ log2n=msb(z); dat.resize(z*2,M::e()),lazy.resize(z*2,M::id()); for(int i=0;i=1;i--)update(i); } void set(int i,const S&x){ i+=z; for(int j=log2n;j>0;j--)push(i>>j); dat[i]=x; i>>=1; while(i){ update(i); i>>=1; } } S get(int i){ i+=z; for(int j=log2n;j>0;j--)push(i>>j); return dat[i]; } void apply(int l,int r,const F&f){ l+=z,r+=z; path_push(l),path_push(r); int l2=l,r2=r; while(l>=1,r>>=1; } path_update(l2),path_update(r2); } S prod(int l,int r){ l+=z,r+=z; path_push(l),path_push(r); S left=M::e(),right=M::e(); while(l>=1,r>>=1; } return M::op(left,right); } inline S all_prod()const{return dat[1];} std::vectorget_all(){ for(int i=1;i(dat.begin()+z,dat.begin()+z+n); } friend std::ostream &operator<<(std::ostream&os,const LazySegmentTree&seg){ std::vectorlazy2(seg.lazy); for(int i=0;i struct RangeAddRangeMin{ static_assert(std::is_arithmetic_v); using S=T; using F=T; static inline S op(const S&x,const S&y){return x::max()/2;} static inline S mapping(const F&f,const S&x,long long){return x+f;} static inline F composition(const F&f,const F&g){return f+g;} static inline F id(){return 0;} static inline void revS(S&x){} static inline S pow(const S&x,long long){return x;} }; struct PermutationTree{ enum node_type{ inc,dec,prime,leaf }; struct node{ int par; int l,r; int x; std::vectorchild; node_type type; }; int root=-1; std::vectornd; PermutationTree(const std::vectorp){ std::vectormn,mx,st; LazySegmentTree>seg(std::vector(p.size())); auto add=[&](int par,int ch)->void { nd[par].child.push_back(ch); nd[ch].par=par; nd[par].l=std::min(nd[par].l,nd[ch].l); nd[par].r=std::max(nd[par].r,nd[ch].r); nd[par].x=std::min(nd[par].x,nd[ch].x); }; for(int i=0;i<(int)p.size();i++){ while(!mn.empty()){ int j=mn.back(); if(p[j]>p[i]){ mn.pop_back(); seg.apply(mn.empty()?0:mn.back()+1,j+1,p[j]-p[i]); } else break; } mn.push_back(i); while(!mx.empty()){ int j=mx.back(); if(p[j] constexpr int carmichael_constexpr(int n){ if(n==998244353)return 998244352; if(n==1000000007)return 1000000006; if(n<=1)return n; int res=1; int t=0; while(n%2==0){ n/=2; t++; } if(t==2)res=2; else if(t>=3)res=1<<(t-2); for(int i=3;i*i<=n;i++)if(n%i==0){ int c=0; while(n%i==0){ n/=i; c++; } int prod=i-1; for(int j=0;j struct mod_int{ private: static constexpr unsigned int umod=static_cast(m); static constexpr unsigned int car=carmichael_constexpr(m); using uint=unsigned int; using mint=mod_int; uint v; static_assert(mval()<=1)return *this; if constexpr(m%8==1){ mint b=2; while(b.pow((m-1)/2).val()==1)b++; int m2=m-1,e=0; while(m2%2==0)m2>>=1,e++; mint x=this->pow((m2-1)/2); mint y=(*this)*x*x; x*=*this; mint z=b.pow(m2); while(y.val()!=1){ int j=0; mint t=y; while(t.val()!=1)t*=t,j++; z=z.pow(1<<(e-j-1)); x*=z; z*=z; y*=z;e=j; } return x; } else if constexpr(m%8==5){ mint ret=this->pow((m+3)/8); if((ret*ret).val()==this->val())return ret; else return ret*mint::raw(2).pow((m-1)/4); } else{ return this->pow((m+1)/4); } } public: using value_type=uint; mod_int():v(0){} template,std::nullptr_t> =nullptr> mod_int(T a){ a%=m; if(a<0)v=a+umod; else v=a; } template,std::nullptr_t> =nullptr> mod_int(T a):v(a%umod){} static constexpr mint raw(int a){ mint ret; ret.v=a; return ret; } inline uint val()const{return this->v;} static constexpr int mod(){return m;} inline mint &operator+=(const mint &b){ this->v+=b.v; if(this->v>=umod)this->v-=umod; return *this; } inline mint &operator-=(const mint &b){ this->v-=b.v; if(this->v>=umod)this->v+=umod; return *this; } inline mint &operator*=(const mint &b){ this->v=((unsigned long long)this->v*b.v)%umod; return *this; } inline mint &operator/=(const mint &b){ *this*=b.inv(); return *this; } inline mint operator+()const{return *this;} inline mint operator-()const{return mint()-*this;} friend inline mint operator+(const mint &a,const mint &b){return mint(a)+=b;} friend inline mint operator-(const mint &a,const mint &b){return mint(a)-=b;} friend inline mint operator*(const mint &a,const mint &b){return mint(a)*=b;} friend inline mint operator/(const mint &a,const mint &b){return mint(a)/=b;} friend inline bool operator==(const mint &a,const mint &b){return a.val()==b.val();} friend inline bool operator!=(const mint &a,const mint &b){return !(a==b);} inline mint operator++(int){ mint ret=*this; *this+=mint::raw(1); return ret; } inline mint operator--(int){ mint ret=*this; *this-=mint::raw(1); return ret; } mint pow(long long n)const{ mint ret=mint::raw(1),a(*this); while(n){ if(n&1)ret*=a; a*=a; n>>=1; } return ret; } inline mint inv()const{ assert(this->v!=0); return pow(car-1); } std::optionalsqrt()const{ if(this->val()<=1||this->pow((m-1)/2)==1)return std::make_optional(this->sqrt_impl()); else return std::nullopt; } static constexpr unsigned int order(){return car;} friend std::istream &operator>>(std::istream &is,mint &b){ long long a; is>>a; b=mint(a); return is; } friend std::ostream &operator<<(std::ostream &os,const mint &b){ os< struct std::hash>{ std::size_t operator()(mod_intx)const{ return std::hash()(x.val()); } }; using mint998=mod_int<998244353>; using mint107=mod_int<1000000007>; using mint=mint998; void SOLVE(){ int n,k; cin>>n>>k; vectorp(n); cin>>p; p--; PermutationTree pt(p); vector>dp(n+1,vector(k+1)); dp[0][0]=1; auto dfs=[&](auto self,int x)->void { if(pt[x].type==pt.prime||pt[x].type==pt.leaf){ rep(i,k)dp[pt[x].r][i+1]+=dp[pt[x].l][i]; if(pt[x].type==pt.leaf)return; } vectors(dp[pt[x].l]); for(int c:pt[x].child){ self(self,c); if(pt[x].type==pt.inc||pt[x].type==pt.dec){ rep(i,k){ dp[pt[c].r][i+1]+=s[i]; dp[pt[c].r][i+1]-=dp[pt[c].l][i]; s[i]+=dp[pt[c].r][i]; } } } }; dfs(dfs,pt.root); rep(i,1,k+1)cout<