#pragma once
template<classmint>structFactorial{staticvoidreserve(intn){inv(n);fact(n);fact_inv(n);}staticmintinv(intn){staticlonglongmod=mint::get_mod();staticvector<mint>buf({0,1});assert(n!=0);if(mod!=mint::get_mod()){mod=mint::get_mod();buf=vector<mint>({0,1});}while((int)buf.capacity()<=n)buf.reserve(buf.capacity()*2);while((int)buf.size()<=n){longlongk=buf.size(),q=(mod+k-1)/k;buf.push_back(q*buf[k*q-mod]);}returnbuf[n];}staticmintfact(intn){staticlonglongmod=mint::get_mod();staticvector<mint>buf({1,1});assert(n>=0);if(mod!=mint::get_mod()){mod=mint::get_mod();buf=vector<mint>({1,1});}while((int)buf.capacity()<=n)buf.reserve(buf.capacity()*2);while((int)buf.size()<=n){longlongk=buf.size();buf.push_back(buf.back()*k);}returnbuf[n];}staticmintfact_inv(intn){staticlonglongmod=mint::get_mod();staticvector<mint>buf({1,1});assert(n>=0);if(mod!=mint::get_mod()){mod=mint::get_mod();buf=vector<mint>({1,1});}if((int)buf.size()<=n)inv(n);while((int)buf.capacity()<=n)buf.reserve(buf.capacity()*2);while((int)buf.size()<=n){longlongk=buf.size();buf.push_back(buf.back()*inv(k));}returnbuf[n];}staticmintbinom(intn,intr){if(r<0||r>n)return0;returnfact(n)*fact_inv(r)*fact_inv(n-r);}staticmintbinom_naive(intn,intr){if(r<0||r>n)return0;mintres=fact_inv(r);for(inti=0;i<r;i++)res*=n-i;returnres;}staticmintmultinom(constvector<int>&r){intn=0;for(auto&x:r){if(x<0)return0;n+=x;}mintres=fact(n);for(auto&x:r)res*=fact_inv(x);returnres;}staticmintP(intn,intr){if(r<0||r>n)return0;returnfact(n)*fact_inv(n-r);}// partition n items to r groups (allow empty group)staticmintH(intn,intr){if(n<0||r<0)return0;returnr==0?1:binom(n+r-1,r);}};/**
* @brief 階乗, 二項係数
*/
#line 2 "modint/factorial.hpp"
template<classmint>structFactorial{staticvoidreserve(intn){inv(n);fact(n);fact_inv(n);}staticmintinv(intn){staticlonglongmod=mint::get_mod();staticvector<mint>buf({0,1});assert(n!=0);if(mod!=mint::get_mod()){mod=mint::get_mod();buf=vector<mint>({0,1});}while((int)buf.capacity()<=n)buf.reserve(buf.capacity()*2);while((int)buf.size()<=n){longlongk=buf.size(),q=(mod+k-1)/k;buf.push_back(q*buf[k*q-mod]);}returnbuf[n];}staticmintfact(intn){staticlonglongmod=mint::get_mod();staticvector<mint>buf({1,1});assert(n>=0);if(mod!=mint::get_mod()){mod=mint::get_mod();buf=vector<mint>({1,1});}while((int)buf.capacity()<=n)buf.reserve(buf.capacity()*2);while((int)buf.size()<=n){longlongk=buf.size();buf.push_back(buf.back()*k);}returnbuf[n];}staticmintfact_inv(intn){staticlonglongmod=mint::get_mod();staticvector<mint>buf({1,1});assert(n>=0);if(mod!=mint::get_mod()){mod=mint::get_mod();buf=vector<mint>({1,1});}if((int)buf.size()<=n)inv(n);while((int)buf.capacity()<=n)buf.reserve(buf.capacity()*2);while((int)buf.size()<=n){longlongk=buf.size();buf.push_back(buf.back()*inv(k));}returnbuf[n];}staticmintbinom(intn,intr){if(r<0||r>n)return0;returnfact(n)*fact_inv(r)*fact_inv(n-r);}staticmintbinom_naive(intn,intr){if(r<0||r>n)return0;mintres=fact_inv(r);for(inti=0;i<r;i++)res*=n-i;returnres;}staticmintmultinom(constvector<int>&r){intn=0;for(auto&x:r){if(x<0)return0;n+=x;}mintres=fact(n);for(auto&x:r)res*=fact_inv(x);returnres;}staticmintP(intn,intr){if(r<0||r>n)return0;returnfact(n)*fact_inv(n-r);}// partition n items to r groups (allow empty group)staticmintH(intn,intr){if(n<0||r<0)return0;returnr==0?1:binom(n+r-1,r);}};/**
* @brief 階乗, 二項係数
*/