#define CP_BUNDLED_SOURCE #ifdef TEMPLATE #else #define TEMPLATE # pragma GCC optimize("O3") #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using uint=unsigned; using ll=long long; using ull=unsigned long long; using ld=long double; using pii=pair; using pll=pair; using i128=__int128; using u128=unsigned __int128; templateusing vc=vector; templateusing vvc=vc>; templateusing vvvc=vvc>; templateusing smpq=priority_queue,greater>; templateusing bipq=priority_queue; #define rep(i,n) for(ll i=0;i<(ll)(n);i++) #define REP(i,j,n) for(ll i=(j);i<(ll)(n);i++) #define DREP(i,n,m) for(ll i=(n);i>=(m);i--) #define drep(i,n) for(ll i=((n)-1);i>=0;i--) #define rall(x) x.rbegin(),x.rend() #define mp(...) make_pair(__VA_ARGS__) #define pb push_back #define fi first #define se second #define is insert #define bg begin() #define ed end() #define all(x) x.begin(),x.end() void scan(int&a) { cin >> a; } void scan(ll&a) { cin >> a; } void scan(string&a) { cin >> a; } void scan(char&a) { cin >> a; } void scan(uint&a) { cin >> a; } void scan(ull&a) { cin >> a; } void scan(bool&a) { cin >> a; } void scan(ld&a){ cin>> a;} template void scan(vector&a) { for(auto&x:a) scan(x); } void read() {} template void read(Head&head, Tail&... tail) { scan(head); read(tail...); } #define INT(...) int __VA_ARGS__; read(__VA_ARGS__); #define LL(...) ll __VA_ARGS__; read(__VA_ARGS__); #define ULL(...) ull __VA_ARGS__; read(__VA_ARGS__); #define STR(...) string __VA_ARGS__; read(__VA_ARGS__); #define VC(type, name, ...) vector name(__VA_ARGS__); read(name); #define VVC(type, name, size, ...) vector> name(size, vector(__VA_ARGS__)); read(name); templatevoid print(T a) { cout << a; } template void print(vectora) { for(int i=0;i<(int)a.size();i++){if(i)cout<<" ";print(a[i]);}cout< void PRT(T a) { print(a); cout < void PRT(Head head, Tail ... tail) { print(head); cout << " "; PRT(tail...); return; } template bool chmin(T &x, F y){ if(x>y){ x=y; return true; } return false; } template bool chmax(T &x, F y){ if(x T floor(T a, T b) { return a / b - (a % b && (a ^ b) < 0); } template T ceil(T x, T y) { return floor(x + y - 1, y); } template T bmod(T x, T y) { return x - y * floor(x, y); } template pair divmod(T x, T y) { T q = floor(x, y); return {q, x - q * y}; } void YesNo(bool b){ cout<<(b?"Yes":"No")<stovi(const string&s,const string&S){ vcv(s.size()); rep(i,s.size()){ auto t=S.find(s[i]); assert(t!=string::npos); v[i]=t; } return v; } template T isqrt(T x){ T F=sqrtl(x); while((F+1)*(F+1)<=x)F++; while(F*F>x)F--; return F; } template vvctrans(const vvc&a){ assert(a.size()&&a[0].size()); vvcb(a[0].size(),vc(a.size())); rep(i,a.size())rep(j,a[0].size()){ b[j][i]=a[i][j]; } return b; } template vctrans(const vc&a){ assert(a.size()&&a[0].size()); vcb(a[0].size(),string(a.size(),0)); rep(i,a.size())rep(j,a[0].size()){ b[j][i]=a[i][j]; } return b; } template int popcount(T n){ return __builtin_popcountll(n); } template L sum(vc&a){ return accumulate(all(a),L(0)); } template vcsubset(T S){ vcans; for(T x=S;x>0;x=(x-1)&S)ans.pb(x); ans.pb(0); return ans; } template T max(vc&a){ return *max_element(all(a)); } template T min(vc&a){ return *min_element(all(a)); } #ifndef COMPRESSER_STRUCT #define COMPRESSER_STRUCT template struct compresser{ vcx; compresser(int n=0){x.reserve(n);} compresser(const vc&xs){ x=xs; } void push(T p){built=false;x.pb(p);} bool built=false; void build(){ if(!chmax(built,1))return; sort(all(x)); x.erase(unique(all(x)),x.end()); } int find(T v){ build(); auto itr=lower_bound(all(x),v)-x.begin(); if(itr==x.size()||x[itr]!=v)return -1; return itr; } int find_next(T v){ build(); return lower_bound(all(x),v)-x.begin(); } int size(){ build(); return x.size(); } T operator[](int i)const{ assert(0<=i&&i vc presum(vc &a){ vc ret(a.size()+1); rep(i,a.size())ret[i+1]=ret[i]+a[i]; return ret; } template vc &operator+=(vc &a,F b){ for (auto&v:a)v += b; return a; } template vc &operator-=(vc&a,F b){ for (auto&v:a)v-=b; return a; } template vc &operator*=(vc&a,F b){ for (auto&v:a)v*=b; return a; } template constexpr T pow(T a,T b){ T res=1; while(b){ if(b&1)res*=a; a*=a; b/=2; } return res; } constexpr ll ten(ll a){ return pow(10,a); } templateconstexpr T inf=numeric_limits::max()/2-1; template int tbit(T x){ using U=make_unsigned_t; U y=(U)x; return y?(int)bit_width(y)-1:-1; } template int lbit(T x){ using U=make_unsigned_t; U y=(U)x; return y?(int)countr_zero(y):-1; } template int tbit(T x,int p){ using U=make_unsigned_t; constexpr int W=numeric_limits::digits; U y=(U)x; if(p<0)return -1; if(p>=W-1)return tbit(y); return tbit(y&((U(1)<<(p+1))-1)); } template int lbit(T x,int p){ using U=make_unsigned_t; constexpr int W=numeric_limits::digits; U y=(U)x; if(p<0)return lbit(y); if(p>=W)return -1; return lbit(y&(~U(0)<>(istream&is,i128&x){ string s;is>>s; x=0; int i=0,neg=0; if(s[0]=='-')neg=1,i=1; for(;i<(int)s.size();i++)x=x*10+s[i]-'0'; if(neg)x=-x; return is; } ostream& operator<<(ostream&os,i128 x){ if(x==0)return os<<0; if(x<0)os<<"-"; u128 y=x<0?-(u128)x:(u128)x; string s; while(y)s.pb('0'+y%10),y/=10; reverse(all(s)); return os<sync_with_stdio(0); #ifdef LOCAL cout<0); mod=mod_; m=(i128(1)<<64)/mod; } unsigned reduce(uint64_t x){ assert(mod>0); x-=(((i128)x*m)>>64)*mod; return x struct dynamic_modint{ using u32=uint32_t; using u64=uint64_t; u32 val; dynamic_modint():val(0){} dynamic_modint(ll x){ ll v=x%get_mod(); if(v<0)v+=get_mod(); val=v; } static dynamic_modint raw(int v){ assert(v>=0); dynamic_modint mi; mi.val=v; return mi; } dynamic_modint &operator+=(const dynamic_modint&m){ if((val+=m.val)>=get_mod())val-=get_mod(); return *this; } dynamic_modint &operator-=(const dynamic_modint&m){ if((val+=(get_mod()-m.val))>=get_mod())val-=get_mod(); return *this; } dynamic_modint &operator*=(const dynamic_modint&m){ val=rem(u64(val)*m.val); return *this; } dynamic_modint &operator/=(const dynamic_modint&m){ val=rem(u64(val)*m.inv().val); return *this; } dynamic_modint operator-() const{ return dynamic_modint(val?get_mod()-val:0); } dynamic_modint operator+() const { return *this; } friend dynamic_modint operator+(dynamic_modint lhs, const dynamic_modint& rhs){ return lhs+=rhs; } friend dynamic_modint operator-(dynamic_modint lhs, const dynamic_modint& rhs){ return lhs-=rhs; } friend dynamic_modint operator*(dynamic_modint lhs, const dynamic_modint& rhs){ return lhs*=rhs; } friend dynamic_modint operator/(dynamic_modint lhs,const dynamic_modint&rhs){ return lhs/=rhs; } bool operator==(const dynamic_modint&p) const{ return p.val==val; } bool operator!=(const dynamic_modint&p) const{ return p.val!=val; } dynamic_modint pow(int64_t n) const{ dynamic_modint res(1),mul(val); while(n){ if(n%2)res*=mul; mul*=mul; n/=2; } return res; } friend ostream&operator<<(ostream&os,const dynamic_modint&p){ os<>(istream&is,dynamic_modint&p){ int64_t x; is>>x; p=dynamic_modint(x); return is; } dynamic_modint inv()const{ int64_t a=val,b=get_mod(),u=1,v=0,t; #ifdef LOCAL assert(gcd(a,b)==1); #endif while(b>0){ t=a/b; swap(a-=t*b,b); swap(u-=t*v,v); } return dynamic_modint(u); } inline static u32 rem(u64 x){return barrett_reduction().reduce(x);} static inline int &get_mod(){ static int mod=0; return mod; } static void set_mod(int md){ assert(0 struct binom_has_get_mod:false_type{}; template struct binom_has_get_mod>:true_type{}; template struct binom{ private: static vector&fact_table(){static vectorv={1};return v;} static vector&invfact_table(){static vectorv={1};return v;} static vector&invs_table(){static vectorv={0};return v;} static int&built_mod(){static int mod=-1;return mod;} public: static void build(int n){ auto&_fact=fact_table(); auto&_invfact=invfact_table(); auto&_invs=invs_table(); if constexpr(binom_has_get_mod::value){ auto mod=mint::get_mod(); if(built_mod()!=mod){ _fact={1}; _invfact={1}; _invs={0}; built_mod()=mod; } } if(n<(int)_fact.size())return; int old=_fact.size(); _fact.resize(n+1); _invfact.resize(n+1); _invs.resize(n+1); if constexpr(binom_has_get_mod::value){ auto mod=mint::get_mod(); for(int i=old;i<=n;i++){ _fact[i]=_fact[i-1]*i; if(i==1)_invs[i]=1; else _invs[i]=-_invs[mod%i]*(mod/i); _invfact[i]=_invfact[i-1]*_invs[i]; } }else{ for(int i=old;i<=n;i++){ _fact[i]=_fact[i-1]*i; _invs[i]=mint(1)/i; _invfact[i]=_invfact[i-1]*_invs[i]; } } } static mint fact(int i){ assert(i>=0); build(i); return fact_table()[i]; } static mint invfact(int i){ assert(i>=0); build(i); return invfact_table()[i]; } static mint inv(int i){ assert(i>0); build(i); return invs_table()[i]; } static mint C(int a,int b){//aCb if(b==0)return 1; if(a<0||b<0||a-b<0)return mint(0); build(a); auto&_fact=fact_table(); auto&_invfact=invfact_table(); return _fact[a]*_invfact[b]*_invfact[a-b]; } static mint iC(int a,int b){//1/aCb if(a<0||b<0||a-b<0)return mint(0); build(a); auto&_fact=fact_table(); auto&_invfact=invfact_table(); return _fact[b]*_fact[a-b]*_invfact[a]; } static mint P(int a,int b){ if(a T extgcd(T a, T b, T &x, T &y) { T d = a; if(b != 0) { d = extgcd(b, a % b, y, x); y -= (a / b) * x; } else { x = 1; y = 0; } return d; } template pair inv(T x,T m){ T a1,a2; T res=extgcd(x,m,a1,a2); T md=m/res; a1=(a1%md+md)%md; return {a1,md}; } template pair mod_solve(T a,T b,T m){//return x s.t. ax=b mod m a%=m,b%=m;if(a<0)a+=m;if(b<0)b+=m; T g=gcd(gcd(a,b),m); a/=g,b/=g,m/=g; if(gcd(a,m)>1)return {-1,-1}; return {(inv(a,m).first*b)%m,inv(a,m).second}; } //x^2 ≡ b (mod p) ll mod_sqrt(ll b,ll p){ static mt19937 mt(random_device{}()); b%=p;if(b<0)b+=p; if(b==0)return 0; if(p==2){ return b; } assert(p>=3); using mint=dynamic_modint<20260801>;mint::set_mod(p); if(mint(b).pow((p-1)/2)==-1){ return -1; } if(p%4==3){ return mint(b).pow((p+1)/4).val; } ll t=[&](){ ll w; while(1){ ll t=mt()%p; w=t*t-b; if(mint(w).pow((p-1)/2)==mint(-1)){ return t; } } assert(0); }(); mint w=mint(t*t-b); using T=pair; auto ml=[&](T a,T b)->T{ return T{a.first*b.first+a.second*b.second*w,a.second*b.first+a.first*b.second}; }; ll e=(p+1)/2; T ans={1,0}; T gy={t,1}; while(e){ if(e%2)ans=ml(ans,gy); gy=ml(gy,gy); e/=2; } return ans.first.val; } template struct static_modint{ static_assert(0=0); static_modint mi; mi.val=v; return mi; } static_modint &operator+=(const static_modint&m){ if((val+=m.val)>=mod)val-=mod; return *this; } static_modint &operator-=(const static_modint&m){ if((val+=(mod-m.val))>=mod)val-=mod; return *this; } static_modint &operator*=(const static_modint&m){ val=u64(val)*m.val%mod; return *this; } static_modint &operator/=(const static_modint&m){ val=u64(val)*m.inv().val%mod; return *this; } static_modint operator-() const{ return static_modint(mod-val); } static_modint operator+() const { return *this; } friend static_modint operator+(static_modint lhs, const static_modint& rhs){ return lhs+=rhs; } friend static_modint operator-(static_modint lhs, const static_modint& rhs){ return lhs-=rhs; } friend static_modint operator*(static_modint lhs, const static_modint& rhs){ return lhs*=rhs; } friend static_modint operator/(static_modint lhs,const static_modint&rhs){ return lhs/=rhs; } bool operator==(const static_modint&p) const{ return p.val==val; } bool operator!=(const static_modint&p) const{ return p.val!=val; } static_modint pow(int64_t n) const{ static_modint res(1),mul(val); while(n){ if(n%2)res*=mul; mul*=mul; n/=2; } return res; } friend ostream&operator<<(ostream&os,const static_modint&p){ os<>(istream&is,static_modint&p){ int64_t x; is>>x; p=static_modint(x); return is; } static_modint inv()const{ int64_t a=val,b=mod,u=1,v=0,t; #ifdef LOCAL assert(gcd(a,b)==1); #endif while(b>0){ t=a/b; swap(a-=t*b,b); swap(u-=t*v,v); } return static_modint(u); } }; #include struct unweighted{ unweighted()=default; unweighted(int){} operator int()const{return 1;} }; template struct edge{ int from,to,id; [[no_unique_address]] T cost; #ifdef LOCAL friend ostream&operator<<(ostream&os,const edge&e){ return os<<"{from:"<struct is_edge:false_type{}; templatestruct is_edge().from),decltype(declval().to),decltype(declval().id),decltype(declval().cost)>>:true_type{}; struct empty_storage{}; template struct static_graph{ constexpr static bool directed(){return is_directed;} using edge=conditional_t::value,T,::edge>; using cost_t=decltype(declval().cost); private: int n,m,added=0; mutable bool csr_built=false; [[no_unique_address]] mutable conditional_t inv_built{}; vc_all_edges; mutable vccsr_start; mutable vccsr_edge; [[no_unique_address]] mutable conditional_t,empty_storage>inv_start; [[no_unique_address]] mutable conditional_t,empty_storage>inv_edge; public: static_graph(int n):n(n),m(-1){assert(n>=0);csr_start.resize(n+1);} static_graph(int n,int m):n(n),m(m){assert(n>=0&&m>=0);csr_start.resize(n+1);_all_edges.reserve(m);} void resize(int size){ assert(n<=size); assert(!csr_built); n=size; csr_start.resize(n+1); } void add_edge(const edge&e){ assert(0<=e.from&&e.from void input(int edge_count){ assert(edge_count>=0); rep(i,edge_count){ INT(a,b); a-=substract; b-=substract; add_edge(a,b); } } void build()const{ if(csr_built)return; csr_built=true; csr_start.assign(n+1,0); for(auto&e:_all_edges){ csr_start[e.from]++; if constexpr(!is_directed)csr_start[e.to]++; } rep(i,n)csr_start[i+1]+=csr_start[i]; csr_edge.resize(csr_start[n]); for(auto it=_all_edges.rbegin();it!=_all_edges.rend();++it){ auto&e=*it; csr_edge[--csr_start[e.from]]=e; if constexpr(!is_directed)csr_edge[--csr_start[e.to]]={e.to,e.from,e.id,e.cost}; } } void build_inv()const{ if constexpr(!is_directed){ build(); return; }else{ if(inv_built)return; inv_built=true; inv_start.assign(n+1,0); for(auto&e:_all_edges){ inv_start[e.to]++; } rep(i,n)inv_start[i+1]+=inv_start[i]; inv_edge.resize(inv_start[n]); for(auto it=_all_edges.rbegin();it!=_all_edges.rend();++it){ auto&e=*it; inv_edge[--inv_start[e.to]]={e.to,e.from,e.id,e.cost}; } } } const vc&all_edges()const{return _all_edges;} int edge_size()const{return (int)_all_edges.size();} edge get_edge(int id)const{ assert(0<=id&&id struct span{ E*l; E* r; E*begin()const{return l;} E*end()const{return r;} int size()const{return r-l;} E&back()const{return r[-1];} E&operator[](int i){return l[i];} const E&operator[](int i)const{return l[i];} }; auto operator[](int u){ assert(0<=u&&u{csr_edge.data()+csr_start[u],csr_edge.data()+csr_start[u+1]}; } auto operator[](int u)const{ assert(0<=u&&u{csr_edge.data()+csr_start[u],csr_edge.data()+csr_start[u+1]}; } auto inv(int u){ assert(0<=u&&u{inv_edge.data()+inv_start[u],inv_edge.data()+inv_start[u+1]}; } } auto inv(int u)const{ assert(0<=u&&u{inv_edge.data()+inv_start[u],inv_edge.data()+inv_start[u+1]}; } } int size()const{return n;} templatevvcadj()const{ vvcres(n,vc(n)); for(auto&e:all_edges()){ res[e.from][e.to]=e.cost; if(directed()==false)res[e.to][e.from]=e.cost; } return res; } void clear(){ added=0; csr_built=false; if constexpr(is_directed)inv_built=false; _all_edges.clear();_all_edges.shrink_to_fit(); csr_start.assign(n+1,0);csr_start.shrink_to_fit(); csr_edge.clear();csr_edge.shrink_to_fit(); if constexpr(is_directed){ inv_start.clear();inv_start.shrink_to_fit(); inv_edge.clear();inv_edge.shrink_to_fit(); } } template void sort(int i,F f){ assert(0<=i&&i void sort_inv(int i,F f){ assert(0<=i&&i static_graphextract(F f)const{ static_graphres(n); for(auto&e:_all_edges)if(f(e))res.add_edge(e); return res; } template static_graph<1,T>reorder(F f)const{ static_graph<1,T>res(n); for(auto&e:_all_edges){ if(f(e))res.add_edge(e); else res.add_edge({e.to,e.from,e.id,e.cost}); } return res; } }; template struct tree{ using Graph=static_graph<0,T>; using edge=typename Graph::edge; using cost_t=typename Graph::cost_t; mutable Graph g; mutable int built_hld=-1; int n; mutable vcin,out,head,size_,par,depth,ord; tree(int n):n(n),g(n,n-1){} void add_edge(const edge&e){ g.add_edge(e); } void add_edge(int a,int b,cost_t cost=1,int id=-1){ g.add_edge(a,b,cost,id); } bool is_to_par(auto&e)const{ return par[e.from]==e.to; } int size()const{ return n; } auto operator[](int u)const{ assert(0<=u&&u void input(){ rep(i,n-1){ INT(a,b); a-=substract; b-=substract; g.add_edge(a,b); } } template void build(int root=0)const{ assert(0<=root&&rootvoid{ depth[u]=d++; auto s=g[u]; int heavy=-1,par_id=-1; rep(i,s.size()){ auto&e=s[i]; if(e.to==v){ par_id=i; continue; } par[e.to]=u; dfs(dfs,e.to,u,d); size_[u]+=size_[e.to]; if(heavy==-1||size_[s[heavy].to]void{ in[u]=timer; ord[timer++]=u; auto s=g[u]; bool first=true; rep(i,s.size()){ auto&e=s[i]; if(e.to==par[u])continue; head[e.to]=first?head[u]:e.to; first=false; dfs(dfs,e.to); } if constexpr(disjoint)out[u]=timer++; else out[u]=timer; };dfs(dfs,root);} rep(u,n){ auto s=g[u]; int ce=s.size()-(par[u]!=-1); if(ce>1)sort(s.begin()+1,s.begin()+ce,[&](const edge&a,const edge&b){return in[a.to]{s.l,s.l}; return typename Graph::template span{s.l,s.l+1}; } auto light_edges(int u)const{ assert(0<=u&&u{s.l,s.l}; return typename Graph::template span{s.l+1,s.l+ce}; } int lca(int a,int b)const{ assert(0<=a&&a0){ int x=I[a]-I[H[a]]; if(x>=k){ return O[I[a]-k]; } k-=x+1; a=P[H[a]]; } return a; } int jump(int s,int t,int k)const{ assert(0<=s&&s=k){ return jumpup(s,k); }else{ return jumpup(t,D-k); } } int to(int x,int y)const{ assert(0<=x&&x>query(int s,int t,bool edge=false)const{ assert(0<=s&&s>rs,rt; while(h[s]!=h[t]){ if(d[h[s]]>d[h[t]]){ rs.push_back({I[s],I[h[s]]}); s=P[h[s]]; }else{ rt.push_back({I[h[t]],I[t]}); t=P[h[t]]; } } if(s!=t||!edge){ if(d[s]>d[t]){ rs.push_back({I[s],I[t]+edge}); }else{ rt.push_back({I[s]+edge,I[t]}); } } rs.reserve(rs.size()+rt.size()); for(auto it=rt.rbegin();it!=rt.rend();++it)rs.push_back(*it); return rs; } pairget_diameter()const{ assert(n>0); auto find_farthest=[&](int from)->int{ vcd(n),p(n,-2),st(1,from); p[from]=-1; int far=from; while(!st.empty()){ int u=st.back(); st.pop_back(); if(d[far]; using B=binom; void solve(){ INT(n,m); vcb(n);rep(i,n)cin>>b[i]; static_graph<0>g(n); g.input<1>(m); vcval(n); vccol(n,-1); queueque; que.push(0);col[0]=0; treet(n); while(que.size()){ auto p=que.front();que.pop(); for(auto&e:g[p]){ if(col[e.to]==-1){ col[e.to]=col[p]^1; t.add_edge(e); que.push(e.to); } } } vc::edge>paredge(n); vcans(m); auto dfs=[&](auto&dfs,int u,int v)->void{ for(auto&e:t[u]){ if(e.to==v)continue; paredge[e.to]=e; dfs(dfs,e.to,u); mint add=b[e.to]-val[e.to]; val[e.to]+=add; ans[e.id]=add; val[u]+=add; dbg(u,e.to,add); } }; dfs(dfs,0,-1); if(val==b){ rep(i,m)cout<coef(n); vcecoef(m); rep(i,n){ for(auto&e:g[i]){ if(col[i]!=col[e.to])continue; auto modify=[&](auto&modify,ll u)->void{ if(u==0)return; ecoef[paredge[u].id]-=coef[u]; coef[paredge[u].from]-=coef[u]; coef[u]=0; modify(modify,paredge[u].from); }; ecoef[e.id]+=1; coef[e.to]+=1,coef[i]+=1; modify(modify,e.to); modify(modify,i); mint nx=((b[0]-val[0])/coef[0]); dbg(nx); rep(i,m){ ans[i]+=ecoef[i]*nx; } rep(i,n)for(auto&e:g[i])if(i> t; while(t--)solve(); }