#pragma once
#include"modular-arithmetic/binpow.hpp"/**
* Author: Teetat T.
* Description: Number Theoretic Transform
* Time: $O(N \log N)$
*/template<classmint>structNTT{usingvm=vector<mint>;staticconstexprmintroot=mint::get_root();static_assert(root!=0,"root must be nonzero");staticvoidntt(vm&a){intn=a.size(),L=31-__builtin_clz(n);vmrt(n);rt[1]=1;for(intk=2,s=2;k<n;k*=2,s++){mintz[]={1,binpow(root,MOD>>s)};for(inti=k;i<2*k;i++)rt[i]=rt[i/2]*z[i&1];}vector<int>rev(n);for(inti=1;i<n;i++)rev[i]=(rev[i/2]|(i&1)<<L)/2;for(inti=1;i<n;i++)if(i<rev[i])swap(a[i],a[rev[i]]);for(intk=1;k<n;k*=2)for(inti=0;i<n;i+=2*k)for(intj=0;j<k;j++){mintz=rt[j+k]*a[i+j+k];a[i+j+k]=a[i+j]-z;a[i+j]+=z;}}staticvmconv(constvm&a,constvm&b){if(a.empty()||b.empty())return{};ints=a.size()+b.size()-1,n=1<<(32-__builtin_clz(s));mintinv=mint(n).inv();vmin1(a),in2(b),out(n);in1.resize(n),in2.resize(n);ntt(in1),ntt(in2);for(inti=0;i<n;i++)out[-i&(n-1)]=in1[i]*in2[i]*inv;ntt(out);returnvm(out.begin(),out.begin()+s);}vmoperator()(constvm&a,constvm&b){returnconv(a,b);}};
#line 2 "modular-arithmetic/binpow.hpp"
/**
* Author: Teetat T.
* Date: 2024-01-15
* Description: n-th power using divide and conquer
* Time: $O(\log b)$
*/template<classT>constexprTbinpow(Ta,llb){Tres=1;for(;b>0;b>>=1,a*=a)if(b&1)res*=a;returnres;}#line 3 "polynomial/ntt.hpp"
/**
* Author: Teetat T.
* Description: Number Theoretic Transform
* Time: $O(N \log N)$
*/template<classmint>structNTT{usingvm=vector<mint>;staticconstexprmintroot=mint::get_root();static_assert(root!=0,"root must be nonzero");staticvoidntt(vm&a){intn=a.size(),L=31-__builtin_clz(n);vmrt(n);rt[1]=1;for(intk=2,s=2;k<n;k*=2,s++){mintz[]={1,binpow(root,MOD>>s)};for(inti=k;i<2*k;i++)rt[i]=rt[i/2]*z[i&1];}vector<int>rev(n);for(inti=1;i<n;i++)rev[i]=(rev[i/2]|(i&1)<<L)/2;for(inti=1;i<n;i++)if(i<rev[i])swap(a[i],a[rev[i]]);for(intk=1;k<n;k*=2)for(inti=0;i<n;i+=2*k)for(intj=0;j<k;j++){mintz=rt[j+k]*a[i+j+k];a[i+j+k]=a[i+j]-z;a[i+j]+=z;}}staticvmconv(constvm&a,constvm&b){if(a.empty()||b.empty())return{};ints=a.size()+b.size()-1,n=1<<(32-__builtin_clz(s));mintinv=mint(n).inv();vmin1(a),in2(b),out(n);in1.resize(n),in2.resize(n);ntt(in1),ntt(in2);for(inti=0;i<n;i++)out[-i&(n-1)]=in1[i]*in2[i]*inv;ntt(out);returnvm(out.begin(),out.begin()+s);}vmoperator()(constvm&a,constvm&b){returnconv(a,b);}};