#pragma once
template<typenamefps>fpsconvolution_large(constfps&a,constfps&b){usingmint=typenamefps::value_type;intlen=1LL<<__builtin_ctz(mint::get_mod()-1);if(a.empty()||b.empty())returnfps{};if((int)a.size()+(int)b.size()-1<=len)returna*b;vector<fps>as,bs;for(inti=0;i<(int)a.size();i+=len/2){fpsv{begin(a)+i,begin(a)+min<int>(i+len/2,a.size())};v.resize(len);v.ntt();as.push_back(v);}for(inti=0;i<(int)b.size();i+=len/2){fpsv{begin(b)+i,begin(b)+min<int>(i+len/2,b.size())};v.resize(len);v.ntt();bs.push_back(v);}vector<fps>cs(as.size()+bs.size()-1,fps(len));for(inti=0;i<(int)as.size();i++){for(intj=0;j<(int)bs.size();j++){for(intk=0;k<len;k++)cs[i+j][k]+=as[i][k]*bs[j][k];}}for(auto&v:cs)v.intt();fpsc(a.size()+b.size()-1);for(inti=0;i<(int)cs.size();i++){intoffset=len/2*i;intje=min<int>(len,c.size()-offset);for(intj=0;j<je;j++)c[j+offset]+=cs[i][j];}returnc;}