#include using namespace std; using Int = long long; struct HLDecomposition { Int n,pos; vector > G; vector vid, head, sub, hvy, par, dep, inv, type; HLDecomposition(){} HLDecomposition(Int sz): n(sz),pos(0),G(n), vid(n,-1),head(n),sub(n,1),hvy(n,-1), par(n),dep(n),inv(n),type(n){} void add_edge(Int u, Int v) { G[u].push_back(v); G[v].push_back(u); } void build(vector rs={0}) { Int c=0; for(Int r:rs){ dfs(r); bfs(r, c++); } } void dfs(Int rt) { using T = pair; stack st; par[rt]=-1; dep[rt]=0; st.emplace(rt,0); while(!st.empty()){ Int v=st.top().first; Int &i=st.top().second; if(i<(Int)G[v].size()){ Int u=G[v][i++]; if(u==par[v]) continue; par[u]=v; dep[u]=dep[v]+1; st.emplace(u,0); }else{ st.pop(); Int res=0; for(Int u:G[v]){ if(u==par[v]) continue; sub[v]+=sub[u]; if(res q({r}); while(!q.empty()){ Int h=q.front();q.pop(); for(Int i=h;i!=-1;i=hvy[i]) { type[i]=c; vid[i]=k++; inv[vid[i]]=i; head[i]=h; for(Int j:G[i]) if(j!=par[i]&&j!=hvy[i]) q.push(j); } } } // for_each(vertex) // [l,r] <- attention!! void for_each(Int u, Int v, const function& f) { while(1){ if(vid[u]>vid[v]) swap(u,v); f(max(vid[head[v]],vid[u]),vid[v]); if(head[u]!=head[v]) v=par[head[v]]; else break; } } // for_each(edge) // [l,r] <- attention!! void for_each_edge(Int u, Int v, const function& f) { while(1){ if(vid[u]>vid[v]) swap(u,v); if(head[u]!=head[v]){ f(vid[head[v]],vid[v]); v=par[head[v]]; } else{ if(u!=v) f(vid[u]+1,vid[v]); break; } } } Int lca(Int u,Int v){ while(1){ if(vid[u]>vid[v]) swap(u,v); if(head[u]==head[v]) return u; v=par[head[v]]; } } Int distance(Int u,Int v){ return dep[u]+dep[v]-2*dep[lca(u,v)]; } }; template struct SegmentTree{ typedef function F; typedef function G; Int n; F f; G g; T d1; E d0; vector dat; SegmentTree(){}; SegmentTree(Int n_,F f,G g,T d1, vector v=vector()): f(f),g(g),d1(d1){ init(n_); if(n_==(Int)v.size()) build(n_,v); } void init(Int n_){ n=1; while(n v){ for(Int i=0;i=0;i--) dat[i]=f(dat[i*2+1],dat[i*2+2]); } void update(Int k,E a){ k+=n-1; dat[k]=g(dat[k],a); while(k>0){ k=(k-1)/2; dat[k]=f(dat[k*2+1],dat[k*2+2]); } } inline T query(Int a,Int b){ T vl=d1,vr=d1; for(Int l=a+n,r=b+n;l>=1,r>>=1) { if(l&1) vl=f(vl,dat[(l++)-1]); if(r&1) vr=f(dat[(--r)-1],vr); } return f(vl,vr); } Int find(Int a,Int b,function &check,Int k,Int l,Int r){ if(!check(dat[k])||r<=a||b<=l) return -1; if(k>=n-1) return k-(n-1); Int m=(l+r)>>1; Int vl=find(a,b,check,k*2+1,l,m); if(~vl) return vl; return find(a,b,check,k*2+2,m,r); } Int find(Int a,Int b,function &check){ return find(a,b,check,0,0,n); } }; struct FastIO{ FastIO(){ cin.tie(0); ios::sync_with_stdio(0); } }fastio_beet; //INSERT ABOVE HERE struct M{ Int a,b,c,d; M():a(1),b(0),c(0),d(1){} M(Int a,Int b,Int c,Int d):a(a),b(b),c(c),d(d){} //M(const M &v):a(v.a),b(v.b),c(v.c),d(v.d){} }E; signed main(){ Int n; cin>>n; HLDecomposition hld(n); vector X,Y; for(Int i=1;i>a>>b; X.emplace_back(a); Y.emplace_back(b); hld.add_edge(a,b); } hld.build(); const Int MOD = 1e9+7; SegmentTree::F f=[MOD](M x,M y){ M r(0,0,0,0); r.a=x.a*y.a+x.b*y.c; r.b=x.a*y.b+x.b*y.d; r.c=x.c*y.a+x.d*y.c; r.d=x.c*y.b+x.d*y.d; r.a%=MOD;r.b%=MOD;r.c%=MOD;r.d%=MOD; return r; }; SegmentTree::G g=[](M x,M y){return y;}; SegmentTree seg(n,f,g,E); Int q; cin>>q; for(Int i=0;i>c; if(c=='x'){ Int v,a,b,c,d; cin>>v>>a>>b>>c>>d; int z=(hld.dep[X[v]]>hld.dep[Y[v]]?X[v]:Y[v]); seg.update(hld.vid[z],M(a,b,c,d)); //cout<>x>>y; M ans=E; hld.for_each_edge(x,y, [&](Int l,Int r){ ans=f(seg.query(l,r+1),ans); //cout<