#pragma once
#include<iostream>usingnamespacestd;template<typenameInt,typenameUInt,typenameLong,typenameULong,intid>structArbitraryLazyMontgomeryModIntBase{usingmint=ArbitraryLazyMontgomeryModIntBase;inlinestaticUIntmod;inlinestaticUIntr;inlinestaticUIntn2;staticconstexprintbit_length=sizeof(UInt)*8;staticUIntget_r(){UIntret=mod;while(mod*ret!=1)ret*=UInt(2)-mod*ret;returnret;}staticvoidset_mod(UIntm){assert(m<(UInt(1u)<<(bit_length-2)));assert((m&1)==1);mod=m,n2=-ULong(m)%m,r=get_r();}UInta;ArbitraryLazyMontgomeryModIntBase():a(0){}ArbitraryLazyMontgomeryModIntBase(constLong&b):a(reduce(ULong(b%mod+mod)*n2)){};staticUIntreduce(constULong&b){return(b+ULong(UInt(b)*UInt(-r))*mod)>>bit_length;}mint&operator+=(constmint&b){if(Int(a+=b.a-2*mod)<0)a+=2*mod;return*this;}mint&operator-=(constmint&b){if(Int(a-=b.a)<0)a+=2*mod;return*this;}mint&operator*=(constmint&b){a=reduce(ULong(a)*b.a);return*this;}mint&operator/=(constmint&b){*this*=b.inverse();return*this;}mintoperator+(constmint&b)const{returnmint(*this)+=b;}mintoperator-(constmint&b)const{returnmint(*this)-=b;}mintoperator*(constmint&b)const{returnmint(*this)*=b;}mintoperator/(constmint&b)const{returnmint(*this)/=b;}booloperator==(constmint&b)const{return(a>=mod?a-mod:a)==(b.a>=mod?b.a-mod:b.a);}booloperator!=(constmint&b)const{return(a>=mod?a-mod:a)!=(b.a>=mod?b.a-mod:b.a);}mintoperator-()const{returnmint(0)-mint(*this);}mintoperator+()const{returnmint(*this);}mintpow(ULongn)const{mintret(1),mul(*this);while(n>0){if(n&1)ret*=mul;mul*=mul,n>>=1;}returnret;}friendostream&operator<<(ostream&os,constmint&b){returnos<<b.get();}friendistream&operator>>(istream&is,mint&b){Longt;is>>t;b=ArbitraryLazyMontgomeryModIntBase(t);return(is);}mintinverse()const{Intx=get(),y=get_mod(),u=1,v=0;while(y>0){Intt=x/y;swap(x-=t*y,y);swap(u-=t*v,v);}returnmint{u};}UIntget()const{UIntret=reduce(a);returnret>=mod?ret-mod:ret;}staticUIntget_mod(){returnmod;}};// id に適当な乱数を割り当てて使うtemplate<intid>usingArbitraryLazyMontgomeryModInt=ArbitraryLazyMontgomeryModIntBase<int,unsignedint,longlong,unsignedlonglong,id>;template<intid>usingArbitraryLazyMontgomeryModInt64bit=ArbitraryLazyMontgomeryModIntBase<longlong,unsignedlonglong,__int128_t,__uint128_t,id>;
#line 2 "modint/arbitrary-montgomery-modint.hpp"
#include<iostream>usingnamespacestd;template<typenameInt,typenameUInt,typenameLong,typenameULong,intid>structArbitraryLazyMontgomeryModIntBase{usingmint=ArbitraryLazyMontgomeryModIntBase;inlinestaticUIntmod;inlinestaticUIntr;inlinestaticUIntn2;staticconstexprintbit_length=sizeof(UInt)*8;staticUIntget_r(){UIntret=mod;while(mod*ret!=1)ret*=UInt(2)-mod*ret;returnret;}staticvoidset_mod(UIntm){assert(m<(UInt(1u)<<(bit_length-2)));assert((m&1)==1);mod=m,n2=-ULong(m)%m,r=get_r();}UInta;ArbitraryLazyMontgomeryModIntBase():a(0){}ArbitraryLazyMontgomeryModIntBase(constLong&b):a(reduce(ULong(b%mod+mod)*n2)){};staticUIntreduce(constULong&b){return(b+ULong(UInt(b)*UInt(-r))*mod)>>bit_length;}mint&operator+=(constmint&b){if(Int(a+=b.a-2*mod)<0)a+=2*mod;return*this;}mint&operator-=(constmint&b){if(Int(a-=b.a)<0)a+=2*mod;return*this;}mint&operator*=(constmint&b){a=reduce(ULong(a)*b.a);return*this;}mint&operator/=(constmint&b){*this*=b.inverse();return*this;}mintoperator+(constmint&b)const{returnmint(*this)+=b;}mintoperator-(constmint&b)const{returnmint(*this)-=b;}mintoperator*(constmint&b)const{returnmint(*this)*=b;}mintoperator/(constmint&b)const{returnmint(*this)/=b;}booloperator==(constmint&b)const{return(a>=mod?a-mod:a)==(b.a>=mod?b.a-mod:b.a);}booloperator!=(constmint&b)const{return(a>=mod?a-mod:a)!=(b.a>=mod?b.a-mod:b.a);}mintoperator-()const{returnmint(0)-mint(*this);}mintoperator+()const{returnmint(*this);}mintpow(ULongn)const{mintret(1),mul(*this);while(n>0){if(n&1)ret*=mul;mul*=mul,n>>=1;}returnret;}friendostream&operator<<(ostream&os,constmint&b){returnos<<b.get();}friendistream&operator>>(istream&is,mint&b){Longt;is>>t;b=ArbitraryLazyMontgomeryModIntBase(t);return(is);}mintinverse()const{Intx=get(),y=get_mod(),u=1,v=0;while(y>0){Intt=x/y;swap(x-=t*y,y);swap(u-=t*v,v);}returnmint{u};}UIntget()const{UIntret=reduce(a);returnret>=mod?ret-mod:ret;}staticUIntget_mod(){returnmod;}};// id に適当な乱数を割り当てて使うtemplate<intid>usingArbitraryLazyMontgomeryModInt=ArbitraryLazyMontgomeryModIntBase<int,unsignedint,longlong,unsignedlonglong,id>;template<intid>usingArbitraryLazyMontgomeryModInt64bit=ArbitraryLazyMontgomeryModIntBase<longlong,unsignedlonglong,__int128_t,__uint128_t,id>;