#include using namespace std; typedef unsigned int ui; typedef unsigned long long ull; typedef long long ll; typedef long double ld; typedef pair pll; typedef pair pdl; typedef pair pld; typedef pair pdd; #ifdef _MSC_VER #endif namespace atcoder{namespace internal{int ceil_pow2(int n){int x=0;while((1U<>64); #endif ui v=(ui)(z-x*_m);if(_m<=v)v+=_m;return v;}};constexpr ll pow_mod_constexpr(ll x,ll n,int m){if(m==1)return 0;ui _m=(ui)(m);ull r=1,y=safe_mod(x,m);while(n){if(n&1)r=(r*y)%_m;y=(y*y)%_m;n>>=1;}return r;}constexpr bool is_prime_constexpr(int n){if(n<=1)return false;if(n==2||n==7||n==61)return true;if(n%2==0)return false;ll d=n-1;while(d%2==0)d/=2;constexpr ll bases[3]={2,7,61};for(ll a:bases){ll t=d,y=pow_mod_constexpr(a,t,n);while(t!=n-1&&y!=1&&y!=n-1){y=y*y%n;t<<=1;}if(y!=n-1&&t%2==0)return false;}return true;} templateconstexpr bool is_prime=is_prime_constexpr(n);constexpr pll inv_gcd(ll a,ll b){a=safe_mod(a, b);if(a==0)return{b,0};ll s=b,t=a,m0=0,m1=1;while(t){ll u=s/t;s-=t*u;m0-=m1*u;auto tmp=s;s=t;t=tmp;tmp=m0;m0=m1;m1=tmp;}if(m0<0)m0+=b/s;return{s,m0};} constexpr int primitive_root_constexpr(int m){if(m==2)return 1;if(m==167772161)return 3;if(m==469762049)return 3;if(m==754974721)return 11;if(m==998244353)return 3;int divs[20]={};divs[0]=2;int cnt=1,x=(m-1)/2;while(x%2==0){x/=2;}for(int i=3;(ll)(i)*i<=x;i+=2){if(x%i==0){divs[cnt++]=i;while(x%i==0){x/=i;}}}if(x>1){divs[cnt++]=x;}for(int g=2;;g++){bool ok=true;for(int i=0;iconstexpr int primitive_root=primitive_root_constexpr(m);ull floor_sum_unsigned(ull n,ull m,ull a,ull b){ull ans=0;while(1){if(a>=m){ans+=n*(n-1)/2*(a/m);a%=m;}if(b>=m){ans+=n*(b/m);b%=m;}ull y_max=a*n+b;if(y_maxusing is_signed_int128=typename conditional::value||is_same::value,true_type,false_type>::type;templateusing is_unsigned_int128=typename conditional::value||is_same::value,true_type,false_type>::type; templateusing make_unsigned_int128=typename std::conditional::value,__uint128_t,unsigned __int128>;templateusing is_integral=typename conditional::value||is_signed_int128::value||is_unsigned_int128::value,true_type,false_type>::type; templateusing is_signed_int=typename conditional<(is_integral::value&&is_signed::value)||is_signed_int128::value,true_type,false_type>::type;template using is_unsigned_int=typename conditional<(is_integral::value&&is_unsigned::value)||is_unsigned_int128::value,true_type,false_type>::type; templateusing to_unsigned=typename conditional::value,make_unsigned_int128,typename conditional::value,make_unsigned,common_type>::type>::type; #else templateusing is_integral=typename is_integral;templateusing is_signed_int=typename conditional::value&&is_signed::value,true_type,false_type>::type;templateusing is_unsigned_int=typename conditional::value&&is_unsigned::value,true_type,false_type>::type;templateusing to_unsigned=typename conditional::value,make_unsigned,common_type>::type; #endif templateusing is_signed_int_t=enable_if_t::value>;templateusing is_unsigned_int_t=enable_if_t::value>;templateusing to_unsigned_t=typename to_unsigned::type;}}namespace atcoder{namespace internal{struct modint_base {};struct static_modint_base:modint_base{};templateusing is_modint=is_base_of;templateusing is_modint_t=enable_if_t::value>;} template* =nullptr>struct static_modint:internal::static_modint_base{using mint=static_modint;public:static constexpr int mod(){return m;}static mint raw(int v){mint x;x._v=v;return x;}static_modint():_v(0){}template* =nullptr>static_modint(T v){ll x=(ll)(v%(ll)(umod()));if(x<0)x+=umod();_v=(ui)(x);}template* =nullptr>static_modint(T v){_v=(ui)(v%umod());}ui val()const{return _v;} mint&operator++(){_v++;if(_v==umod())_v=0;return*this;}mint&operator--(){if(_v==0)_v=umod();_v--;return*this;}mint operator++(int){mint result=*this;++*this;return result;}mint operator--(int){mint result=*this;--*this;return result;}mint&operator+=(const mint& rhs){_v+=rhs._v;if(_v>=umod())_v-=umod();return*this;}mint&operator-=(const mint& rhs){_v-=rhs._v;if(_v>=umod())_v+=umod();return*this;}mint&operator*=(const mint& rhs){ull z=_v;z*=rhs._v;_v=(ui)(z%umod());return*this;} mint&operator/=(const mint& rhs){return*this=*this*rhs.inv();}mint operator+()const{return*this;}mint operator-()const{return mint()-*this;}mint pow(ll n)const{assert(0<=n);mint x=*this,r=1;while(n){if(n&1)r*=x;x*=x;n>>=1;}return r;}mint inv()const{if(prime){assert(_v);return pow(umod()-2);}else{auto eg=internal::inv_gcd(_v,m);assert(eg.first==1);return eg.second;}} friend mint operator+(const mint&lhs,const mint&rhs){return mint(lhs)+=rhs;}friend mint operator-(const mint&lhs,const mint&rhs){return mint(lhs)-=rhs;}friend mint operator*(const mint&lhs,const mint&rhs){return mint(lhs)*=rhs;}friend mint operator/(const mint&lhs,const mint&rhs){return mint(lhs)/=rhs;}friend bool operator==(const mint&lhs,const mint&rhs){return lhs._v==rhs._v;}friend bool operator!=(const mint&lhs,const mint&rhs){return lhs._v!=rhs._v;}private:ui _v;static constexpr ui umod(){return m;}static constexpr bool prime=internal::is_prime;}; templatestruct dynamic_modint:internal::modint_base{using mint=dynamic_modint;public:static int mod(){return(int)(bt.umod());}static void set_mod(int m){assert(1<=m);bt=internal::barrett(m);}static mint raw(int v){mint x;x._v=v;return x;}dynamic_modint():_v(0){}template* =nullptr>dynamic_modint(T v){ll x=(ll)(v%(ll)(mod()));if(x<0)x+=mod();_v=(ui)(x);}template* =nullptr>dynamic_modint(T v){_v=(ui)(v%mod());}ui val()const{return _v;} mint&operator++(){_v++;if(_v==umod())_v=0;return*this;}mint&operator--(){if(_v==0)_v=umod();_v--;return*this;}mint operator++(int){mint result=*this;++*this;return result;}mint operator--(int){mint result=*this;--*this;return result;}mint&operator+=(const mint&rhs){_v+=rhs._v;if(_v>=umod())_v-=umod();return*this;}mint&operator-=(const mint&rhs){_v+=mod()-rhs._v;if(_v>=umod())_v-=umod();return*this;} mint&operator*=(const mint&rhs){_v=bt.mul(_v,rhs._v);return*this;}mint&operator/=(const mint& rhs){return*this=*this*rhs.inv();}mint operator+()const{return*this;}mint operator-()const{return mint()-*this;}mint pow(ll n)const{assert(0<=n);mint x=*this,r=1;while(n){if(n&1)r*=x;x*=x;n>>=1;}return r;}mint inv()const{auto eg=internal::inv_gcd(_v,mod());assert(eg.first==1);return eg.second;} friend mint operator+(const mint&lhs,const mint&rhs){return mint(lhs)+=rhs;}friend mint operator-(const mint&lhs,const mint&rhs){return mint(lhs)-=rhs;}friend mint operator*(const mint&lhs,const mint&rhs){return mint(lhs)*=rhs;}friend mint operator/(const mint&lhs,const mint&rhs){return mint(lhs)/=rhs;}friend bool operator==(const mint&lhs,const mint&rhs){return lhs._v==rhs._v;}friend bool operator!=(const mint&lhs,const mint&rhs){return lhs._v!=rhs._v;}private:ui _v;static internal::barrett bt;static ui umod(){return bt.umod();}}; templateinternal::barrett dynamic_modint::bt(998244353);using modint998244353=static_modint<998244353>;using modint1000000007=static_modint<1000000007>;using modint=dynamic_modint<-1>;namespace internal{templateusing is_static_modint=is_base_of;templateusing is_static_modint_t=enable_if_t::value>;templatestruct is_dynamic_modint:public false_type{};templatestruct is_dynamic_modint>:public true_type{};templateusing is_dynamic_modint_t=enable_if_t::value>;}} namespace atcoder{namespace internal{template,internal::is_static_modint_t* =nullptr>struct fft_info{static constexpr int rank2=bsf_constexpr(mint::mod()-1);arrayroot;arrayiroot;arrayrate2;arrayirate2;arrayrate3;arrayirate3; fft_info(){root[rank2]=mint(g).pow((mint::mod()-1)>>rank2);iroot[rank2]=root[rank2].inv();for(int i=rank2-1;i>=0;i--){root[i]=root[i+1]*root[i+1];iroot[i]=iroot[i+1]*iroot[i+1];}{mint prod=1,iprod=1;for(int i=0;i<=rank2-2;i++){rate2[i]=root[i+2]*prod;irate2[i]=iroot[i+2]*iprod;prod*=iroot[i+2];iprod*=root[i+2];}}{mint prod=1,iprod=1;for(int i=0;i<=rank2-3;i++){rate3[i]=root[i+3]*prod;irate3[i]=iroot[i+3]*iprod;prod*=iroot[i+3];iprod*=root[i+3];}}}}; template* =nullptr>void butterfly(std::vector&a){int n=int(a.size()),h=internal::ceil_pow2(n);static const fft_infoinfo;int len=0;while(len* =nullptr>void butterfly_inv(std::vector&a){int n=int(a.size()),h=internal::ceil_pow2(n);static const fft_info info;int len=h;while(len){if(len==1){int p=1<<(h-len);mint irot=1;for(int s=0;s<(1<<(len-1));s++){int offset=s<<(h-len+1);for(int i=0;i* =nullptr>vectorconvolution_naive(const vector&a,const vector&b){int n=int(a.size()),m=int(b.size());vectorans(n+m-1);if(n* =nullptr>vectorconvolution_fft(vector a,vector b){int n=int(a.size()),m=int(b.size());int z=1<* =nullptr>vectorconvolution(vector&&a,vector&&b){int n=int(a.size()),m=int(b.size());if(!n||!m)return{};if(min(n,m)<=60)return convolution_naive(a,b);return internal::convolution_fft(a,b);} template* =nullptr>vectorconvolution(const vector&a,const vector&b){int n=int(a.size()),m=int(b.size());if(!n||!m)return{};if(min(n,m)<=60)return convolution_naive(a,b);return internal::convolution_fft(a,b);}template::value>* =nullptr>vectorconvolution(const vector&a,const vector&b){int n=int(a.size()),m=int(b.size());if(!n||!m)return{}; using mint=static_modint;vectora2(n),b2(m);for(int i=0;ic(n+m-1);for(int i=0;iconvolution_ll(const vector&a,const vector&b){int n=int(a.size()),m=int(b.size());if(!n||!m)return{};static constexpr ull MOD1=754974721;static constexpr ull MOD2=167772161;static constexpr ull MOD3=469762049;static constexpr ull M2M3=MOD2*MOD3;static constexpr ull M1M3=MOD1*MOD3;static constexpr ull M1M2=MOD1*MOD2;static constexpr ull M1M2M3=MOD1*MOD2*MOD3; static constexpr ull i1=internal::inv_gcd(MOD2*MOD3,MOD1).second;static constexpr ull i2=internal::inv_gcd(MOD1*MOD3,MOD2).second;static constexpr ull i3=internal::inv_gcd(MOD1*MOD2,MOD3).second;auto c1=convolution(a,b);auto c2=convolution(a,b);auto c3=convolution(a,b);vectorc(n+m-1);for(int i=0;i>groups(){vectorleader_buf(_n),group_size(_n);for(int i=0;i<_n;i++){leader_buf[i]=leader(i);group_size[leader_buf[i]]++;}vector>result(_n);for(int i=0;i<_n;i++){result[i].reserve(group_size[i]);} for(int i=0;i<_n;i++){result[leader_buf[i]].push_back(i);}result.erase(remove_if(result.begin(),result.end(),[&](const vector&v){return v.empty();}),result.end());return result;}private:int _n;vectorparent_or_size;};} namespace atcoder{templatestruct fenwick_tree{using U=internal::to_unsigned_t;public:fenwick_tree():_n(0){}explicit fenwick_tree(int n):_n(n),data(n){}void add(int p,T x){assert(0<=p&&p<_n);p++;while(p<=_n){data[p-1]+=U(x);p+=p&-p;}}T sum(int l,int r){assert(0<=l&&l<=r&&r<=_n);return sum(r)-sum(l);}private:int _n;vectordata;U sum(int r){U s=0;while(r>0){s+=data[r-1];r-=r&-r;}return s;}};} namespace atcoder{templatestruct lazy_segtree{public:lazy_segtree():lazy_segtree(0){}explicit lazy_segtree(int n):lazy_segtree(std::vector(n,e())){}explicit lazy_segtree(const vector&v):_n(int(v.size())){log=internal::ceil_pow2(_n);size=1<(2*size,e());lz=vector(size,id());for(int i=0;i<_n;i++)d[size+i]=v[i];for(int i=size-1;i>=1;i--){update(i);}}void set(int p,S x){assert(0<=p&&p<_n);p+=size;for(int i=log;i>=1;i--)push(p>>i);d[p]=x;for(int i=1;i<=log;i++)update(p>>i);} S get(int p){assert(0<=p&&p<_n);p+=size;for(int i=log;i>=1;i--)push(p>>i);return d[p];}S prod(int l,int r){assert(0<=l&&l<=r&&r<=_n);if(l==r)return e();l+=size;r+=size;for(int i=log;i>=1;i--){if(((l>>i)<>i);if(((r>>i)<>i);}S sml=e(),smr=e();while(l>=1;r>>=1;}return op(sml, smr);}S all_prod(){return d[1];}void apply(int p,F f){assert(0<=p&&p<_n);p+=size;for(int i=log;i>=1;i--)push(p>>i);d[p]=mapping(f,d[p]);for(int i=1;i<=log;i++)update(p>>i);} void apply(int l,int r,F f){assert(0<=l&&l<=r&&r<=_n);if(l==r)return;l+=size;r+=size;for(int i=log;i>=1;i--){if(((l>>i)<>i);if(((r>>i)<>i);}{int l2=l,r2=r;while(l>=1;r>>=1;}l=l2;r=r2;}for(int i=1;i<=log;i++){if(((l>>i)<>i);if(((r>>i)<>i);}}templateint max_right(int l){return max_right(l,[](S x){return g(x);});}templateint max_right(int l,G g){assert(0<=l&&l<=_n);assert(g(e()));if(l==_n)return _n;l+=size;for(int i=log;i>=1;i--)push(l>>i);S sm=e();do{while(l%2==0)l>>=1; if(!g(op(sm,d[l]))){while(lint min_left(int r){return min_left(r,[](S x){return g(x);});}templateint min_left(int r,G g){assert(0<=r&&r<=_n);assert(g(e()));if(r==0)return 0;r+=size;for(int i=log;i>=1;i--)push((r-1)>>i);S sm=e();do{r--;while(r>1&&(r%2))r>>=1; if(!g(op(d[r],sm))){while(rd;vectorlz;void update(int k){d[k]=op(d[2*k],d[2*k+1]);}void all_apply(int k,F f){d[k]=mapping(f,d[k]);if(k>=1;}return r;}ll inv_mod(ll x,ll m){assert(1<=m);auto z=internal::inv_gcd(x,m);assert(z.first==1);return z.second;}pll crt(const vector&r,const vector&m){assert(r.size()==m.size());int n=int(r.size());ll r0=0,m0=1;for(int i=0;istruct simple_queue{vectorpayload;int pos=0;void reserve(int n){payload.reserve(n);}int size()const{return int(payload.size())-pos;}bool empty()const{return pos==int(payload.size());}void push(const T&t){payload.push_back(t);}T&front(){return payload[pos];}void clear(){payload.clear();pos=0;}void pop(){pos++;}};}} namespace atcoder{templatestruct mf_graph{public:mf_graph():_n(0){}explicit mf_graph(int n):_n(n),g(n){}int add_edge(int from,int to,Cap cap){assert(0<=from&&from<_n);assert(0<=to&&to<_n);assert(0<=cap);int m=int(pos.size());pos.push_back({from,int(g[from].size())});int from_id=int(g[from].size());int to_id=int(g[to].size());if(from==to)to_id++;g[from].push_back(_edge{to,to_id,cap});g[to].push_back(_edge{from,from_id,0});return m;}struct edge{int from,to;Cap cap,flow;}; edge get_edge(int i){int m=int(pos.size());assert(0<=i&&iedges(){int m=int(pos.size());vectorresult;for(int i=0;i::max());}Cap flow(int s,int t,Cap flow_limit){assert(0<=s&&s<_n);assert(0<=t&&t<_n);assert(s!=t);vectorlevel(_n),iter(_n);internal::simple_queueque;auto bfs=[&](){fill(level.begin(),level.end(),-1);level[s]=0;que.clear();que.push(s);while(!que.empty()){int v=que.front();que.pop();for(auto e:g[v]){if(e.cap==0||level[e.to]>=0)continue;level[e.to]=level[v]+1;if(e.to==t)return;que.push(e.to);}}};auto dfs=[&](auto self,int v,Cap up){if(v==s)return up;Cap res=0;int level_v=level[v]; for(int&i=iter[v];imin_cut(int s){vectorvisited(_n);internal::simple_queueque;que.push(s);while(!que.empty()){int p=que.front();que.pop();visited[p]=true; for(auto e:g[p]){if(e.cap&&!visited[e.to]){visited[e.to]=true;que.push(e.to);}}}return visited;}private:int _n;struct _edge{int to,rev;Cap cap;};vector>pos;vector>g;};}namespace atcoder{namespace internal{templatestruct csr{vectorstart;vectorelist;explicit csr(int n,const vector>&edges):start(n+1),elist(edges.size()){for(auto e:edges){start[e.first+1]++;}for(int i=1;i<=n;i++){start[i]+=start[i-1];}auto counter=start;for(auto e:edges){elist[counter[e.first]++]=e.second;}}};}} namespace atcoder{templatestruct mcf_graph{public:mcf_graph(){}explicit mcf_graph(int n):_n(n){}int add_edge(int from,int to,Cap cap,Cost cost){assert(0<=from&&from<_n);assert(0<=to&&to<_n);assert(0<=cap);assert(0<=cost);int m=int(_edges.size());_edges.push_back({from,to,cap,0,cost});return m;}struct edge{int from,to;Cap cap,flow;Cost cost;};edge get_edge(int i){int m=int(_edges.size());assert(0<=i&&iedges(){return _edges;}pairflow(int s,int t){return flow(s,t,numeric_limits::max());} pairflow(int s,int t, Cap flow_limit){return slope(s,t,flow_limit).back();}vector>slope(int s,int t){return slope(s,t,numeric_limits::max());}vector>slope(int s,int t,Cap flow_limit){assert(0<=s&&s<_n);assert(0<=t&&t<_n);assert(s!=t);int m=int(_edges.size());vectoredge_idx(m);auto g=[&](){vectordegree(_n),redge_idx(m);vector>elist;elist.reserve(2*m);for(int i=0;i(_n,elist);for(int i=0;i_edges;struct _edge{int to,rev;Cap cap;Cost cost;};vector>slope(internal::csr<_edge>&g,int s,int t,Cap flow_limit){vector>dual_dist(_n);vectorprev_e(_n);vectorvis(_n); struct Q{Cost key;int to;bool operator<(Q r)const{return key>r.key;}};vectorque_min;vectorque;auto dual_ref=[&](){for(int i=0;i<_n;i++){dual_dist[i].second=numeric_limits::max();}fill(vis.begin(),vis.end(),false);que_min.clear();que.clear();size_t heap_r=0;dual_dist[s].second=0;que_min.push_back(s);while(!que_min.empty()||!que.empty()){int v;if(!que_min.empty()){v=que_min.back();que_min.pop_back();}else{while(heap_rcost){Cost dist_to=dist_v+cost;dual_dist[e.to].second=dist_to;prev_e[e.to]=e.rev;if(dist_to==dist_v){que_min.push_back(e.to);}else{que.push_back(Q{dist_to,e.to});}}}}if(!vis[t]){return false;} for(int v=0;v<_n;v++){if(!vis[v])continue;dual_dist[v].first-=dual_dist[t].second-dual_dist[v].second;}return true;};Cap flow=0;Cost cost=0,prev_cost_per_flow=-1;vector>result={{Cap(0),Cost(0)}};while(flow>scc_ids(){auto g=csr(_n,edges);int now_ord=0,group_num=0;vectorvisited,low(_n),ord(_n,-1),ids(_n);visited.reserve(_n);auto dfs=[&](auto self,int v)->void{low[v]=ord[v]=now_ord++;visited.push_back(v);for(int i=g.start[v];i>scc(){auto ids=scc_ids();int group_num=ids.first;vectorcounts(group_num);for(auto x:ids.second)counts[x]++;vector>groups(ids.first);for(int i=0;i>edges;};}} namespace atcoder{struct scc_graph{public:scc_graph():internal(0){}explicit scc_graph(int n):internal(n){}void add_edge(int from,int to){int n=internal.num_vertices();assert(0<=from&&from>scc(){return internal.scc();}private:internal::scc_graph internal;};}namespace atcoder{templatestruct segtree{public:segtree():segtree(0){}explicit segtree(int n):segtree(vector(n,e())){}explicit segtree(const vector&v):_n(int(v.size())){log=internal::ceil_pow2(_n);size=1<(2*size,e()); for(int i=0;i<_n;i++){d[size+i]=v[i];}for(int i=size-1;i>=1;i--){update(i);}}void set(int p,S x){assert(0<=p&&p<_n);p+=size;d[p]=x;for(int i=1;i<=log;i++)update(p>>i);}S get(int p)const{assert(0<=p&&p<_n);return d[p+size];}S prod(int l,int r)const{assert(0<=l&&l<=r&&r<=_n);S sml=e(),smr=e();l+=size;r+=size;while(l>=1;r>>=1;}return op(sml,smr);}S all_prod() const{return d[1];}templateint max_right(int l)const{return max_right(l,[](S x){return f(x);});}templateint max_right(int l,F f)const{assert(0<=l&&l<=_n);assert(f(e())); if(l==_n){return _n;}l+=size;S sm=e();do{while(l%2==0)l>>=1;if(!f(op(sm,d[l]))){while(lint min_left(int r)const{return min_left(r,[](S x){return f(x);});}templateint min_left(int r,F f)const{assert(0<=r&&r<=_n);assert(f(e()));if(r==0)return 0;r+=size;S sm=e();do{r--;while(r>1&&(r%2))r>>=1;if(!f(op(d[r],sm))){while(rd; void update(int k){d[k]=op(d[2*k],d[2*k+1]);}};}namespace atcoder{namespace internal{vectorsa_naive(const vector&s){int n=int(s.size());vectorsa(n);iota(sa.begin(),sa.end(),0);sort(sa.begin(),sa.end(),[&](int l,int r){if(l==r)return false;while(lsa_doubling(const vector&s){int n=int(s.size());vectorsa(n),rnk=s,tmp(n);iota(sa.begin(),sa.end(),0);for(int k=1;kvectorsa_is(const vector&s,int upper){int n=int(s.size());if(n==0)return{};if(n==1)return{0};if(n==2){if(s[0]sa(n);vectorls(n);for(int i=n-2;i>=0;i--){ls[i]=(s[i]==s[i+1])?ls[i+1]:(s[i]sum_l(upper+1),sum_s(upper+1); for(int i=0;i&lms){fill(sa.begin(),sa.end(),-1);vectorbuf(upper+1);copy(sum_s.begin(),sum_s.end(),buf.begin());for(auto d:lms){if(d==n)continue;sa[buf[s[d]]++]=d;}copy(sum_l.begin(),sum_l.end(),buf.begin());sa[buf[s[n-1]]++]=n-1;for(int i=0;i=1&&!ls[v-1]){sa[buf[s[v-1]]++]=v-1;}}copy(sum_l.begin(),sum_l.end(),buf.begin());for(int i=n-1;i>=0;i--){int v=sa[i];if(v>=1&&ls[v-1]){sa[--buf[s[v-1]+1]]=v-1;}}}; vectorlms_map(n+1,-1);int m=0;for(int i=1;ilms;lms.reserve(m);for(int i=1;isorted_lms;sorted_lms.reserve(m);for(int v:sa){if(lms_map[v]!=-1)sorted_lms.push_back(v);}vectorrec_s(m);int rec_upper=0;rec_s[lms_map[sorted_lms[0]]]=0;for(int i=1;i(rec_s,rec_upper);for(int i=0;isuffix_array(const vector&s,int upper){assert(0<=upper);for(int d:s){assert(0<=d&&d<=upper);}auto sa=internal::sa_is(s,upper);return sa;}templatevectorsuffix_array(const vector&s){int n=int(s.size());vectoridx(n);iota(idx.begin(),idx.end(),0);sort(idx.begin(),idx.end(),[&](int l,int r){return s[l]s2(n);int now=0;for(int i=0;isuffix_array(const string&s){int n=int(s.size());vectors2(n);for(int i=0;ivectorlcp_array(const vector&s,const vector&sa){int n=int(s.size());assert(n>=1);vectorrnk(n);for(int i=0;ilcp(n-1);int h=0;for(int i=0;i0)h--;if(rnk[i]==0)continue;int j=sa[rnk[i]-1];for(;j+hlcp_array(const string&s,const vector&sa){int n=int(s.size());vectors2(n);for(int i=0;ivectorz_algorithm(const vector&s){int n=int(s.size());if(n==0)return{};vectorz(n);z[0]=0;for(int i=1,j=0;iz_algorithm(const string&s){int n=int(s.size());vectors2(n);for(int i=0;ianswer(){return _answer;}private:int _n;vector_answer;internal::scc_graph scc;};} //——————————————————Atcoder Library——————————————————— #define endl "\n" //←これ using namespace atcoder; #define rep(i,n) for(ll i=0; i=b; i--) #define pb push_back #define np next_permutation #define fi first #define se second #define all(v) v.begin(),v.end() #define srt(v) sort(v.begin(),v.end()) #define trs(v) sort(v.rbegin(),v.rend()) #define rev(v) reverse(v.begin(),v.end()) #define lb(v,x) (lower_bound(v.begin(),v.end(),x)-v.begin()) #define ub(v,x) (upper_bound(v.begin(),v.end(),x)-v.begin()) #define cou(x) __builtin_popcountll(x) const ld pi=acos(-1.0); const ll INF = 1LL<<61; templatebool chmax(T&a,const T&b){if(abool chmin(T&a,const T&b){if(b vl(ll n,ll x){vector re(n,x);return re;} vector vd(ll n,ld x){vector re(n,x);return re;} vector vs(ll n,ll m){vector re(n,string(m,'.'));return re;} vector> vl(ll n, ll m,ll x){vector> re(n,vector(m,x));return re;} vector> vd(ll n, ll m,ld x){vector> re(n,vector(m,x));return re;} vector>> vl(ll a, ll b, ll c,ll x){vector>> re(a,vector>(b,vector(c,x)));return re;} vector>> vd(ll a, ll b, ll c,ld x){vector>> re(a,vector>(b,vector(c,x)));return re;} vector>>> vl(ll a, ll b, ll c,ll d,ll x){vector>>> re(a,vector>>(b,vector>(c,vector(d,x))));return re;} vector>>> vd(ll a, ll b, ll c,ll d,ld x){vector>>> re(a,vector>>(b,vector>(c,vector(d,x))));return re;} templatevoid out(T x) {cout << x << endl;} templatevoid out(T x,T y) {cout << x << " " << y << endl;} templatevoid out(T x,T y,T z) {cout << x << " " << y << " " << z << endl;} templatevoid out(T a,T b,T c,T d) {cout << a << " " << b << " " << c << " " << d << endl;} templatevoid out(T a,T b,T c,T d,T e) {cout << a << " " << b << " " << c << " " << d << " " << e << endl;} templatevoid out(T a,T b,T c,T d,T e,T f) {cout << a << " " << b << " " << c << " " << d << " " << e << " " << f << endl;} templatevoid out(pair p) {cout << p.fi << " " << p.se << endl;} templatevoid vout(vector &v){if(v.size()>0){for(auto it = v.begin(); it < v.end(); it++){cout << *it;if(it != v.end()-1) cout<<" ";}}cout<void pout(vector &v){if(v.size()>0){for(auto it = v.begin(); it < v.end(); it++){cout << *it+1;if(it != v.end()-1) cout<<" ";}}cout<void vout(vector> &v){if(v.size()>0){for(auto it = v.begin(); it < v.end(); it++) {vout(*it);}}} templatevoid vout(vector> &v){if(v.size()>0){for(auto it = v.begin(); it < v.end(); it++){out(*it);}}} void sout(vector &v){if(v.size()>0){for(auto it = v.begin(); it < v.end(); it++){cout << *it < YES={"NO","YES"}; vector Yes={"No","Yes"}; vector yes={"no","yes"}; vector POS={"IMPOSSIBLE","POSSIBLE"}; vector Pos={"Impossible","Possible"}; vector pos={"impossible","possible"}; vector FIS={"SECOND","FIRST"}; vector Fis={"Second","First"}; vector fis={"second","first"}; //———————————————tento 転倒数————————————————— ll tento(vectorv){ ll n=v.size(); vector v2(n); vector vp(n); rep(i,n) vp[i]={v[i],i}; sort(all(vp)); rep(i,n) v2[vp[i].se]=i; fenwick_tree bit(n); ll re=0; rep(i,n){ re+=i-bit.sum(0,v2[i]+1); bit.add(v2[i], 1); } return re; } //——————————————————————————————————————————————— //——————————————————————————————LIS 最長増加部分列———————————————————————————————— template size_t lis(const vector& a,bool strict=true){ vector lis; for(auto& p : a){ typename vector::iterator it; if(strict) it = lower_bound(begin(lis),end(lis),p); else it = upper_bound(begin(lis),end(lis),p); if(end(lis) == it) lis.emplace_back(p); else *it = p; } return lis.size(); } //————————————————————————————————————————————————————————————————————————————— //ベクター入力 vector pin(ll n){ vector re(n); rep(i,n) cin>>re[i]; return re; } //ベクター入力 -1 vector hin(ll n){ vector re(n); rep(i,n){ cin>>re[i]; re[i]--; } return re; } //二次元ベクター入力 vector> ppin(ll h,ll w){ vector> re(h,vector(w)); rep(i,h) rep(j,w) cin>>re[i][j]; return re; } //ストリング入力 vector stin(ll n){ vector re(n); rep(i,n) cin>>re[i]; return re; } //グラフ入力 vector> gin(ll n,ll m,ll hoko,ll pl){ vector> re(n); rep(i,m){ ll a,b; cin>>a>>b; a+=pl;b+=pl; re[a].pb(b); if(hoko==2) re[b].pb(a); } return re; } //グラフdist vector gdis(vector> &g, ll st){ ll n=g.size(); vector dist(n,INF); queue que; dist[st]=0; que.push(st); while(!que.empty()){ ll x=que.front(); que.pop(); for(ll nx:g[x]){ if(dist[nx]!=INF) continue; dist[nx]=dist[x]+1; que.push(nx); } } return dist; } //グラフ距離入力 vector> ggin(ll n,ll m,ll hoko,ll pl){ vector> re(n); rep(i,m){ ll a,b,c; cin>>a>>b>>c; a+=pl;b+=pl; re[a].pb({b,c}); if(hoko==2) re[b].pb({a,c}); } return re; } //グラフ距離dist vector gdis(vector> &g, ll st){ ll n=g.size(); vector dist(n,INF); priority_queue,greater> que; dist[st]=0; que.push({0,st}); while(!que.empty()){ pll z=que.top(); que.pop(); ll x=z.se; if(dist[x]!=z.fi) continue; for(pll nz:g[x]){ ll nx=nz.fi; ll ny=nz.se; if(dist[nx]<=dist[x]+ny) continue; dist[nx]=dist[x]+ny; que.push({dist[nx],nx}); } } return dist; } //intの最大値2147483647 ≒ 2×10^9 //long longの最大値9223372036854775807 ≒ 9×10^18 //実行時間制約2秒では2×10^8回くらいまで計算できる //「#define endl "\n"」はインタラクティブで消す!!! //using mint = modint998244353; using mint = modint1000000007; //using mint = modint; //下でmodint::set_mod(m); void out(mint &x) {out(x.val());} void out(mint &x,mint &y) {out(x.val(),y.val());} void out(mint &x,mint &y,mint &z) {out(x.val(),y.val(),z.val());} void out(mint &x,mint &y,mint &z,mint &a) {out(x.val(),y.val(),z.val(),a.val());} void out(ll &x,mint &y) {out(x,(ll)y.val());} void out(mint &x,ll &y) {out((ll)x.val(),y);} void out(ll &x,ll &y,mint &z) {out(x,y,(ll)z.val());} void out(ll &x,mint &y,mint &z) {out(x,(ll)y.val(),(ll)z.val());} vector vm(ll n){vector re(n,0);return re;} vector> vm(ll n, ll m){vector> re(n,vector(m,0));return re;} vector>> vm(ll n, ll m, ll l){vector>> re(n,vector>(m,vector(l,0)));return re;} vector>>> vm(ll a, ll b, ll c, ll d){vector>>> re(a,vector>>(b,vector>(c,vector(d,0))));return re;} void vout(vector &v){ll n=v.size();rep(i,n-1) cout<> &v){ll n=v.size();if(n>0) rep(i,n) vout(v[i]);} vector vx={1,-1,0,0,1,-1,1,-1,0}; vector vy={0,0,1,-1,1,-1,-1,1,0}; int main(){ cin.tie(0); ios::sync_with_stdio(false); cout<>n; ll x=0,y=0,z=0; rep(i,n){ ll a; cin>>a; if(a==1) x++; else if(a==2) y++; else z++; } ll ans=x*(x-1)+y*(y-1)/2+z*(z-1)/2+3*x*y+y*z+2*z*x; out(ans); }