#define PROBLEM "https://judge.yosupo.jp/problem/range_affine_range_sum"
#include"template.hpp"
#include"modular-arithmetic/modint.hpp"
#include"data-structure/link-cut-tree/lazy-link-cut-tree.hpp"
#include"group/monoid-action/add-count-affine.hpp"usingmint=mint998;usingMonoid=AddCountMonoid<mint>;usingAction=AddCountAffineAction<mint>;usingT=Monoid::value_type;intmain(){cin.tie(nullptr)->sync_with_stdio(false);intn,q;cin>>n>>q;usingLCT=LazyLinkCutTree<Action>;usingPtr=LCT::Ptr;usingNode=LCT::Node;LCTlct;vector<Ptr>ptr(n);for(inti=0;i<n;i++){mintx;cin>>x;ptr[i]=newNode(Monoid::make(x));}for(inti=1;i<n;i++){lct.link(ptr[i-1],ptr[i]);}while(q--){intop;cin>>op;if(op){intl,r;cin>>l>>r;cout<<lct.fold(ptr[l],ptr[r-1]).first<<"\n";}else{intl,r,b,c;cin>>l>>r>>b>>c;lct.apply(ptr[l],ptr[r-1],T(b,c));}}}
#line 1 "verify/yosupo/data-structure/link-cut-tree/lazy-link-cut-tree/range_affine_range_sum.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/range_affine_range_sum"
#line 2 "template.hpp"
#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;usingdb=longdouble;usingi128=__int128_t;usingu32=uint32_t;usingu64=uint64_t;template<classT>usingPQ=priority_queue<T,vector<T>,greater<T>>;constintINF=INT_MAX/2;constllLINF=LLONG_MAX/4;constdbDINF=numeric_limits<db>::infinity();constdbEPS=1e-9;constdbPI=acos(db(-1));#define ALL(a) a.begin(),a.end()
#define RALL(a) a.rbegin(),a.rend()
#define SZ(a) (int)(a.size())
#define SORT(a) sort(ALL(a))
#define RSORT(a) sort(RALL(a))
#define REV(a) reverse(ALL(a))
#define UNI(a) a.erase(unique(ALL(a)),a.end())
#define LB(a,x) (int)(lower_bound(ALL(a),x)-a.begin())
#define UB(a,x) (int)(upper_bound(ALL(a),x)-a.begin())
#define FIND(a,x) (int)(find(ALL(a),x)-a.begin())
#define COUNT(a,x) (int)count(ALL(a),x)
#define MIN(a) *min_element(ALL(a))
#define MAX(a) *max_element(ALL(a))
template<classT,classU>boolchmin(T&a,Ub){returnb<a?a=b,1:0;}template<classT,classU>boolchmax(T&a,Ub){returna<b?a=b,1:0;}template<classT>Tfloor(Ta,Tb){returna/b-((a^b)<0&&a%b);}template<classT>Tceil(Ta,Tb){returna/b+((a^b)>=0&&a%b);}intpopcnt(llx){return__builtin_popcountll(x);}inttopbit(llx){returnx==0?-1:63-__builtin_clzll(x);}intlowbit(llx){returnx==0?-1:__builtin_ctzll(x);}template<classT,classU>TSUM(constU&a){returnaccumulate(ALL(a),T{});}template<classT>vector<int>argsort(constvector<T>&a){vector<int>p(SZ(a));iota(ALL(p),0);stable_sort(ALL(p),[&](inti,intj){returna[i]<a[j];});returnp;}template<classT,size_tD=0>structVecBuilder{array<size_t,D>d;VecBuilder<T,D+1>operator[](size_tn)const{VecBuilder<T,D+1>res{};for(size_ti=0;i<D;i++)res.d[i]=d[i];res.d[D]=n;returnres;}template<size_tI=0>autobuild(constT&x)const{ifconstexpr(I+1==D)returnvector<T>(d[I],x);elsereturnvector<decltype(build<I+1>(x))>(d[I],build<I+1>(x));}autooperator()(constT&x=T())const{static_assert(D>0);returnbuild(x);}};template<classT>inlineconstexprVecBuilder<T>VEC{};mt19937rng(chrono::steady_clock::now().time_since_epoch().count());mt19937_64rng64(chrono::steady_clock::now().time_since_epoch().count());#line 2 "modular-arithmetic/modint.hpp"
/**
* Author: Teetat T.
* Date: 2026-04-15
* Description: modular arithmetic operations
*/template<intmod,introot=0>structModInt{usingmint=ModInt;static_assert(mod>0,"mod must be positive");intx;constexprModInt():x(0){}constexprModInt(llx):x((x%=mod)<0?x+mod:x){}constexprexplicitoperatorint()const{returnx;}constexprintval()const{returnx;}constexprstaticintget_mod(){returnmod;}constexprstaticmintget_root(){returnmint(root);}constexprmintoperator-()const{mintres;res.x=x?mod-x:0;returnres;}constexprmintoperator+()const{return*this;}constexprmintinv()const{inta=x,b=mod,u=1,v=0,q=0;while(b>0){q=a/b;swap(a-=q*b,b);swap(u-=q*v,v);}returnmint(u);}constexprmintpow(lln)const{mintres=1,a=*this;for(;n>0;a*=a,n>>=1)if(n&1)res*=a;returnres;}constexprmint&operator+=(constmint&o){if((x+=o.x)>=mod)x-=mod;return*this;}constexprmint&operator-=(constmint&o){if((x-=o.x)<0)x+=mod;return*this;}constexprmint&operator*=(constmint&o){x=(ll(x)*o.x)%mod;return*this;}constexprmint&operator/=(constmint&o){return*this*=o.inv();}constexprmintoperator+(constmint&o)const{returnmint(*this)+=o;}constexprmintoperator-(constmint&o)const{returnmint(*this)-=o;}constexprmintoperator*(constmint&o)const{returnmint(*this)*=o;}constexprmintoperator/(constmint&o)const{returnmint(*this)/=o;}constexprmint&operator++(){return*this+=mint(1);}constexprmint&operator--(){return*this-=mint(1);}constexprmintoperator++(int){mintres=*this;*this+=mint(1);returnres;}constexprmintoperator--(int){mintres=*this;*this-=mint(1);returnres;}constexprbooloperator==(constmint&o)const{returnx==o.x;}constexprbooloperator!=(constmint&o)const{returnx!=o.x;}constexprbooloperator<(constmint&o)const{returnx<o.x;}friendistream&operator>>(istream&is,mint&o){llx{};is>>x;o=mint(x);returnis;}friendostream&operator<<(ostream&os,constmint&o){returnos<<o.x;}};usingmint998=ModInt<998244353,3>;usingmint107=ModInt<1000000007>;#line 2 "data-structure/link-cut-tree/splay-tree-base.hpp"
/**
* Author: Teetat T.
* Date: 2024-04-13
* Description: Splay Tree. splay(u) will make node u be the root of the tree in amortized O(log n) time.
*/template<classNode>structSplayTreeBase{usingPtr=Node*;boolis_root(Ptrt){return!(t->p)||(t->p->l!=t&&t->p->r!=t);}// The parent of the root stores the path parant in link cut tree.intsize(Ptrt){returnt?t->size:0;}virtualvoidpush(Ptrt){};virtualvoidpull(Ptrt){};intpos(Ptrt){if(t->p){if(t->p->l==t)return-1;if(t->p->r==t)return1;}return0;}voidrotate(Ptrt){Ptrx=t->p,y=x->p;if(pos(t)==-1){if((x->l=t->r))t->r->p=x;t->r=x,x->p=t;}else{if((x->r=t->l))t->l->p=x;t->l=x,x->p=t;}pull(x),pull(t);if((t->p=y)){if(y->l==x)y->l=t;if(y->r==x)y->r=t;}}voidsplay(Ptrt){if(!t)return;push(t);while(!is_root(t)){Ptrx=t->p;if(is_root(x)){push(x),push(t);rotate(t);}else{Ptry=x->p;push(y),push(x),push(t);if(pos(x)==pos(t))rotate(x),rotate(t);elserotate(t),rotate(t);}}}voidsplay_kth(Ptr&t,intk){assert(0<=k&&k<size(t));while(true){push(t);if(k<size(t->l))t=t->l;elseif(size(t->l)==k)break;else{k-=size(t->l)+1;t=t->r;}}splay(t);}Ptrget_first(Ptrt){while(t->l)push(t),t=t->l;splay(t);returnt;}Ptrget_last(Ptrt){while(t->r)push(t),t=t->r;splay(t);returnt;}Ptrmerge(Ptrl,Ptrr){splay(l),splay(r);if(!l)returnr;if(!r)returnl;l=get_last(l);l->r=r;r->p=l;pull(l);returnl;}pair<Ptr,Ptr>split(Ptrt,intk){if(!t)return{nullptr,nullptr};if(k==0)return{nullptr,t};if(k==size(t))return{t,nullptr};splay_kth(t,k-1);Ptrx=t->r;t->r=x->p=nullptr;pull(t);return{t,x};}voidinsert(Ptr&t,intk,Ptrv){splay(t);autox=split(t,k);t=merge(merge(x.first,v),x.second);}voiderase(Ptr&t,intk){splay(t);autox=split(t,k);autoy=split(x.second,1);// delete y.first;t=merge(x.first,y.second);}template<classT>Ptrbuild(constvector<T>&v){if(v.empty())returnnullptr;function<Ptr(int,int)>build=[&](intl,intr){if(l==r)returnnewNode(v[l]);intm=(l+r)/2;returnmerge(build(l,m),build(m+1,r));};returnbuild(0,v.size()-1);}};#line 2 "data-structure/link-cut-tree/lazy-reversible-bbst.hpp"
/**
* Author: Teetat Info.
* Date: 2024-04-13
* Description: Lazy Reversible BBST Base.
*/template<classTree,classNode,classMonoidAction>structLazyReversibleBBST:Tree{usingTree::merge;usingTree::split;usingtypenameTree::Ptr;usingInfoMonoid=typenameMonoidAction::InfoMonoid;usingTagMonoid=typenameMonoidAction::TagMonoid;usingInfo=typenameMonoidAction::Info;usingTag=typenameMonoidAction::Tag;LazyReversibleBBST()=default;Infosum(Ptrt){returnt?t->sum:InfoMonoid::unit();}voidpull(Ptrt){if(!t)return;push(t);t->size=1;t->sum=t->val;t->revsum=t->val;if(t->l){t->size+=t->l->size;t->sum=InfoMonoid::op(t->l->sum,t->sum);t->revsum=InfoMonoid::op(t->revsum,t->l->revsum);}if(t->r){t->size+=t->r->size;t->sum=InfoMonoid::op(t->sum,t->r->sum);t->revsum=InfoMonoid::op(t->r->revsum,t->revsum);}}voidpush(Ptrt){if(!t)return;if(t->rev){toggle(t->l);toggle(t->r);t->rev=false;}if(t->lz!=TagMonoid::unit()){propagate(t->l,t->lz);propagate(t->r,t->lz);t->lz=TagMonoid::unit();}}voidtoggle(Ptrt){if(!t)return;swap(t->l,t->r);swap(t->sum,t->revsum);t->rev^=true;}voidpropagate(Ptrt,constTag&v){if(!t)return;t->val=MonoidAction::op(t->val,v);t->sum=MonoidAction::op(t->sum,v);t->revsum=MonoidAction::op(t->revsum,v);t->lz=TagMonoid::op(t->lz,v);}voidapply(Ptr&t,intl,intr,constTag&v){if(l>r)return;autox=split(t,l);autoy=split(x.second,r-l+1);propagate(y.first,v);t=merge(x.first,merge(y.first,y.second));}Infoquery(Ptr&t,intl,intr){if(l>r)returnInfoMonoid::unit();autox=split(t,l);autoy=split(x.second,r-l+1);Infores=sum(y.first);t=merge(x.first,merge(y.first,y.second));returnres;}voidreverse(Ptr&t,intl,intr){if(l>r)return;autox=split(t,l);autoy=split(x.second,r-l+1);toggle(y.first);t=merge(x.first,merge(y.first,y.second));}};#line 4 "data-structure/link-cut-tree/lazy-reversible-splay-tree.hpp"
/**
* Author: Teetat T.
* Date: 2024-04-13
* Description: Lazy Reversible Splay Tree.
*/template<classMonoidAction>structLazyReversibleSplayTreeNode{usingPtr=LazyReversibleSplayTreeNode*;usingInfoMonoid=typenameMonoidAction::InfoMonoid;usingTagMonoid=typenameMonoidAction::TagMonoid;usingInfo=typenameMonoidAction::Info;usingTag=typenameMonoidAction::Tag;usingvalue_type=Info;Ptrl,r,p;Infoval,sum,revsum;Taglz;intsize;boolrev;LazyReversibleSplayTreeNode(constInfo&_val=InfoMonoid::unit(),constTag&_lz=TagMonoid::unit()):l(),r(),p(),val(_val),sum(_val),revsum(_val),lz(_lz),size(1),rev(false){}};template<classMonoidAction>structLazyReversibleSplayTree:LazyReversibleBBST<SplayTreeBase<LazyReversibleSplayTreeNode<MonoidAction>>,LazyReversibleSplayTreeNode<MonoidAction>,MonoidAction>{usingNode=LazyReversibleSplayTreeNode<MonoidAction>;};#line 2 "data-structure/link-cut-tree/link-cut-tree-base.hpp"
/**
* Author: Teetat T.
* Date: 2024-05-19
* Description: Link Cut Tree Base.
* Usage:
* evert(u): make u be the root of the tree.
* link(u,v): attach u to v.
* cut(u,v): remove edge between u and v.
* get_root(u): get the root of the tree containing u.
* lca(u,v): get the lowest common ancestor of u and v.
* fold(u,v): get the value of the path from u to v.
*/template<classSplay>structLinkCutTreeBase:Splay{usingNode=typenameSplay::Node;usingPtr=Node*;usingT=typenameNode::value_type;Ptrexpose(Ptrt){Ptrpc=nullptr;// preferred childfor(Ptrcur=t;cur;cur=cur->p){this->splay(cur);cur->r=pc;this->pull(cur);pc=cur;}this->splay(t);returnpc;}voidevert(Ptrt){// make t be the root of the treeexpose(t);this->toggle(t);this->push(t);}voidlink(Ptru,Ptrv){// attach u to vevert(u);expose(v);u->p=v;}voidcut(Ptru,Ptrv){// cut edge between u and vevert(u);expose(v);assert(u->p==v);v->l=u->p=nullptr;this->pull(v);}Ptrget_root(Ptrt){expose(t);while(t->l)this->push(t),t=t->l;this->splay(t);returnt;}Ptrlca(Ptru,Ptrv){if(get_root(u)!=get_root(v))returnnullptr;expose(u);returnexpose(v);}voidset_val(Ptrt,constT&val){this->evert(t);t->val=val;this->pull(t);}Tget_val(Ptrt){this->evert(t);returnt->val;}Tfold(Ptru,Ptrv){evert(u);expose(v);returnv->sum;}};#line 4 "data-structure/link-cut-tree/lazy-link-cut-tree.hpp"
/**
* Author: Teetat T.
* Date: 2024-08-02
* Description: Lazy Link Cut Tree.
* Usage: using Lct = LazyLinkCutTree<Action>;
* using Ptr = Lct::Ptr;
* using Node = Lct::Node;
* vector<Ptr> ptr(n);
* for(int i=0;i<n;i++)ptr[i]=new Node(val[i]);
* auto link=[&](int u,int v){
* Lct::link(ptr[u],ptr[v]);
* };
* auto cut=[&](int u,int v){
* Lct::cut(ptr[u],ptr[v]);
* };
* auto update=[&](int u,int v,const Action::Tag &val){
* Lct::apply(ptr[u],ptr[v],val);
* };
* auto query=[&](int u,int v){
* return Lct::fold(ptr[u],ptr[v]);
* };
*/template<classMonoidAction>structLazyLinkCutTree:LinkCutTreeBase<LazyReversibleSplayTree<MonoidAction>>{usingbase=LinkCutTreeBase<LazyReversibleSplayTree<MonoidAction>>;usingPtr=typenamebase::Ptr;usingTag=typenameMonoidAction::Tag;voidapply(Ptru,Ptrv,constTag&val){this->evert(u);this->expose(v);this->propagate(v,val);}};#line 2 "group/monoid/affine.hpp"
/**
* Author: Teetat T.
* Date: 2024-04-14
* Description: Affine Transformation Monoid class.
*/template<classT>structAffineMonoid{usingP=pair<T,T>;usingvalue_type=P;staticconstexprPop(constP&x,constP&y){returnP(x.first*y.first,x.second*y.first+y.second);}staticconstexprPunit(){returnP(T(1),T(0));}staticconstexprTeval(constP&f,constT&x){returnf.first*x+f.second;}};#line 2 "group/monoid/add-count.hpp"
/**
* Author: Teetat T.
* Date: 2024-04-14
* Description: Add & Count Monoid class.
*/template<classT>structAddCountMonoid{usingP=pair<T,ll>;usingvalue_type=P;staticconstexprPop(constP&x,constP&y){returnP(x.first+y.first,x.second+y.second);}staticconstexprPinverse(constP&x){returnP(-x.first,-x.second);}staticconstexprPunit(){returnP(T(0),0LL);}staticconstexprPmake(constT&x){returnP(x,1LL);}};#line 4 "group/monoid-action/add-count-affine.hpp"
/**
* Author: Teetat T.
* Date: 2024-04-14
* Description: Affine to Add & Count Action class.
*/template<classT>structAddCountAffineAction{usingInfoMonoid=AddCountMonoid<T>;usingTagMonoid=AffineMonoid<T>;usingInfo=typenameInfoMonoid::value_type;usingTag=typenameTagMonoid::value_type;staticconstexprInfoop(constInfo&a,constTag&b){returnInfo(a.first*b.first+T(a.second)*b.second,a.second);}};#line 6 "verify/yosupo/data-structure/link-cut-tree/lazy-link-cut-tree/range_affine_range_sum.test.cpp"
usingmint=mint998;usingMonoid=AddCountMonoid<mint>;usingAction=AddCountAffineAction<mint>;usingT=Monoid::value_type;intmain(){cin.tie(nullptr)->sync_with_stdio(false);intn,q;cin>>n>>q;usingLCT=LazyLinkCutTree<Action>;usingPtr=LCT::Ptr;usingNode=LCT::Node;LCTlct;vector<Ptr>ptr(n);for(inti=0;i<n;i++){mintx;cin>>x;ptr[i]=newNode(Monoid::make(x));}for(inti=1;i<n;i++){lct.link(ptr[i-1],ptr[i]);}while(q--){intop;cin>>op;if(op){intl,r;cin>>l>>r;cout<<lct.fold(ptr[l],ptr[r-1]).first<<"\n";}else{intl,r,b,c;cin>>l>>r>>b>>c;lct.apply(ptr[l],ptr[r-1],T(b,c));}}}