template<typenameT>constexprstd::tuple<T,T,T>Exgcd(constT&a,constT&b){if(b==T{}){return{a,T{1},T{}};}auto[gcd,x0,y0]=Exgcd(b,a%b);Tx=y0,y=x0-(a/b)*y0;return{gcd,x,y};}template<typenameT>constexprTnormalize(Tx,Tmod){x%=mod;if(x<0){x+=mod;}returnx;}template<typenameT>constexprTInv(Tval,Tmod){auto[gcd,x,y]=Exgcd<decltype(mod)>(val,mod);assert(gcd==T{1}&&"The modular inverse does not exist.");returnnormalize(x);}
template<automod>classModInt{private:static_assert(mod>=1LL,"The modulus must be a positive integer.");usingT=decltype(mod);Tvalue;staticconstexprstd::tuple<T,T,T>Exgcd(constT&a,constT&b){if(b==T{}){return{a,T{1},T{}};}auto[gcd,x0,y0]=Exgcd(b,a%b);Tx=y0,y=x0-(a/b)*y0;return{gcd,x,y};}public:constexprModInt():value(T{}){}template<typenameV>constexprModInt(constV&v){value=(static_cast<T>(v%mod)+mod)%mod;}constexprModIntinv()const{auto[gcd,x,y]=Exgcd(value,mod);// It could be hold that -mod < x < mod.
assert(gcd==T{1}&&"The modular inverse does not exist.");returnModInt(x);}// calculation operator overloading
constexprModIntoperator-()const{returnModInt(value==0?0:mod-value);}constexprModInt&operator+=(constModInt&rhs){value+=rhs.value;value%=mod;return*this;}constexprModInt&operator-=(constModInt&rhs){value+=mod;value-=rhs.value;value%=mod;return*this;}constexprModInt&operator*=(constModInt&rhs){value=static_cast<T>((static_cast<i128>(value)*rhs.value)%mod);return*this;}constexprModInt&operator/=(constModInt&rhs){*this*=rhs.inv();return*this;}friendconstexprModIntoperator+(constModInt&a,constModInt&b){ModIntres=a;res+=b;returnres;}friendconstexprModIntoperator-(constModInt&a,constModInt&b){ModIntres=a;res-=b;returnres;}friendconstexprModIntoperator*(constModInt&a,constModInt&b){ModIntres=a;res*=b;returnres;}friendconstexprModIntoperator/(constModInt&a,constModInt&b){ModIntres=a;res/=b;returnres;}// bool operator overloading
friendconstexprbooloperator>(constModInt&a,constModInt&b){returna.value>b.value;}friendconstexprbooloperator>=(constModInt&a,constModInt&b){returna.value>=b.value;}friendconstexprbooloperator<(constModInt&a,constModInt&b){returna.value<b.value;}friendconstexprbooloperator<=(constModInt&a,constModInt&b){returna.value<=b.value;}friendconstexprbooloperator==(constModInt&a,constModInt&b){returna.value==b.value;}friendconstexprbooloperator!=(constModInt&a,constModInt&b){returna.value!=b.value;}// stream operator overloading
friendstd::ostream&operator<<(std::ostream&os,constModInt&x){os<<x.value;returnos;}friendstd::istream&operator>>(std::istream&is,ModInt&x){Tv;if(is>>v){x=ModInt(v);}returnis;}};constexpri64mod=1'000'000'007LL;usingZ=ModInt<mod>;template<typenameT>Zmpow(Zbase,Texp){assert(exp>=0);Zres=1;while(exp>0){if(exp&1)res*=base;base*=base;exp>>=1;}returnres;}