//#define _GLIBCXX_DEBUG #include using namespace std; #define endl '\n' #define lfs cout<= (ll)(n); i--) using ll = long long; using ld = long double; const ll MOD1 = 1e9+7; const ll MOD9 = 998244353; const ll INF = 1e18; using P = pair; template using PQ = priority_queue; template using QP = priority_queue,greater>; templatebool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;} templatebool chmax(T1 &a,T2 b){if(avoid ans(bool x,T1 y,T2 z){if(x)cout<void anss(T1 x,T2 y,T3 z){ans(x!=y,x,z);}; templatevoid debug(const T &v,ll h,ll w,string sv=" "){for(ll i=0;ivoid debug(const T &v,ll n,string sv=" "){if(n!=0)cout<void debug(const vector&v){debug(v,v.size());} templatevoid debug(const vector>&v){for(auto &vv:v)debug(vv,vv.size());} templatevoid debug(stack st){while(!st.empty()){cout<void debug(queue st){while(!st.empty()){cout<void debug(deque st){while(!st.empty()){cout<void debug(PQ st){while(!st.empty()){cout<void debug(QP st){while(!st.empty()){cout<void debug(const set&v){for(auto z:v)cout<void debug(const multiset&v){for(auto z:v)cout<void debug(const array &a){for(auto z:a)cout<void debug(const map&v){for(auto z:v)cout<<"["<vector>vec(ll x, ll y, T w){vector>v(x,vector(y,w));return v;} ll gcd(ll x,ll y){ll r;while(y!=0&&(r=x%y)!=0){x=y;y=r;}return y==0?x:y;} vectordx={1,-1,0,0,1,1,-1,-1};vectordy={0,0,1,-1,1,-1,1,-1}; templatevector make_v(size_t a,T b){return vector(a,b);} templateauto make_v(size_t a,Ts... ts){return vector(a,make_v(ts...));} templateostream &operator<<(ostream &os, const pair&p){return os << p.first << " " << p.second;} templateostream &operator<<(ostream &os, const vector &v){for(auto &z:v)os << z << " ";os<<"|"; return os;} templatevoid rearrange(vector&ord, vector&v){ auto tmp = v; for(int i=0;ivoid rearrange(vector&ord,Head&& head, Tail&&... tail){ rearrange(ord, head); rearrange(ord, tail...); } template vector ascend(const vector&v){ vectorord(v.size());iota(ord.begin(),ord.end(),0); sort(ord.begin(),ord.end(),[&](int i,int j){return make_pair(v[i],i) vector descend(const vector&v){ vectorord(v.size());iota(ord.begin(),ord.end(),0); sort(ord.begin(),ord.end(),[&](int i,int j){return make_pair(v[i],-i)>make_pair(v[j],-j);}); return ord; } template vector inv_perm(const vector&ord){ vectorinv(ord.size()); for(int i=0;i0);return n>=0?n/div:(n-div+1)/div;} ll CEIL(ll n,ll div){assert(div>0);return n>=0?(n+div-1)/div:n/div;} ll digitsum(ll n){ll ret=0;while(n){ret+=n%10;n/=10;}return ret;} ll modulo(ll n,ll d){return (n%d+d)%d;}; templateT min(const vector&v){return *min_element(v.begin(),v.end());} templateT max(const vector&v){return *max_element(v.begin(),v.end());} templateT acc(const vector&v){return accumulate(v.begin(),v.end(),T(0));}; templateT reverse(const T &v){return T(v.rbegin(),v.rend());}; //mt19937 mt(chrono::steady_clock::now().time_since_epoch().count()); int popcount(ll x){return __builtin_popcountll(x);}; int poplow(ll x){return __builtin_ctzll(x);}; int pophigh(ll x){return 63 - __builtin_clzll(x);}; templateT poll(queue &q){auto ret=q.front();q.pop();return ret;}; templateT poll(priority_queue &q){auto ret=q.top();q.pop();return ret;}; templateT poll(QP &q){auto ret=q.top();q.pop();return ret;}; templateT poll(stack &s){auto ret=s.top();s.pop();return ret;}; ll MULT(ll x,ll y){if(LLONG_MAX/x<=y)return LLONG_MAX;return x*y;} ll POW2(ll x, ll k){ll ret=1,mul=x;while(k){if(mul==LLONG_MAX)return LLONG_MAX;if(k&1)ret=MULT(ret,mul);mul=MULT(mul,mul);k>>=1;}return ret;} ll POW(ll x, ll k){ll ret=1;for(int i=0;i struct edge { int to; T cost; int id; edge():id(-1){}; edge(int to, T cost = 1, int id = -1):to(to), cost(cost), id(id){} operator int() const { return to; } }; template using Graph = vector>>; template Graphrevgraph(const Graph &g){ Graphret(g.size()); for(int i=0;i Graph readGraph(int n,int m,int indexed=1,bool directed=false,bool weighted=false){ Graph ret(n); for(int es = 0; es < m; es++){ int u,v; T w=1; cin>>u>>v;u-=indexed,v-=indexed; if(weighted)cin>>w; ret[u].emplace_back(v,w,es); if(!directed)ret[v].emplace_back(u,w,es); } return ret; } template Graph readParent(int n,int indexed=1,bool directed=true){ Graphret(n); for(int i=1;i>p; p-=indexed; ret[p].emplace_back(i); if(!directed)ret[i].emplace_back(p); } return ret; } template struct Compress{ vectorv; Compress(){ } Compress(const vector&input){ add(input); build(); } template Compress(const vector &head,const Args& ...input){ add(head, input...); build(); } template Compress(const T &head,const Args& ...input){ add(head, input...); build(); } void build(){ sort(v.begin(), v.end()); v.erase(unique(v.begin(),v.end()),v.end()); } void add(const vector&add){ v.insert(v.end(),add.begin(), add.end()); } template void add(const Head& head,const Tail& ...tail){ add(head); add(tail...); } void add(T val){ v.push_back(val); } int next(T val){ return lower_bound(v.begin(), v.end(), val) - v.begin(); } int prev(T val){ return upper_bound(v.begin(), v.end(), val) - v.begin() - 1; } bool exist(T val){ return binary_search(v.begin(), v.end(), val); } T val(int x){ return v[x]; } vectorcompress(const vector&input){ vectorret(input.size()); for(int i=0;i struct LazySegmentTree { ll sz, height, n; vector< Monoid > data; vector< OperatorMonoid > lazy; const F f; const G g; const H h; Monoid M1; OperatorMonoid OM0; LazySegmentTree(ll n, const F &f,const G &g, const H &h, Monoid M1, OperatorMonoid OM0):n(n),f(f),g(g),h(h),M1(M1),OM0(OM0){ sz = 1; height = 0; while(sz < n) sz <<= 1, height++; data.assign(2 * sz, M1); lazy.assign(2 * sz, OM0); } void set(ll k, const Monoid &x) { data[k + sz] = x; } void build() { for(ll k = sz - 1; k > 0; k--) { data[k] = f(data[2 * k + 0], data[2 * k + 1]); } } inline void propagate(ll k) { if(lazy[k] != OM0) { lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]); lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]); data[k] = reflect(k); lazy[k] = OM0; } } inline Monoid reflect(ll k) { return lazy[k] == OM0 ? data[k] : g(data[k], lazy[k]); } inline void recalc(ll k) { while(k >>= 1) data[k] = f(reflect(2 * k + 0), reflect(2 * k + 1)); } inline void thrust(ll k) { for(ll i = height; i > 0; i--) propagate(k >> i); } void update(ll a, ll b, const OperatorMonoid &x) { if(a>=b)return; thrust(a += sz); thrust(b += sz - 1); for(ll l = a, r = b + 1; l < r; l >>= 1, r >>= 1) { if(l & 1) lazy[l] = h(lazy[l], x), ++l; if(r & 1) --r, lazy[r] = h(lazy[r], x); } recalc(a); recalc(b); } void update(ll a,const Monoid &x){ thrust(a += sz); data[a] = x; lazy[a] = OM0; recalc(a); } Monoid query(ll a, ll b) { if(a>=b)return M1; thrust(a += sz); thrust(b += sz - 1); Monoid L = M1, R = M1; for(ll l = a, r = b + 1; l < r; l >>= 1, r >>= 1) { if(l & 1) L = f(L, reflect(l++)); if(r & 1) R = f(reflect(--r), R); } return f(L, R); } Monoid operator[](const ll &k) { return query(k, k + 1); } template< typename C > ll find_subtree(ll a, const C &check, Monoid &M, bool type) { while(a < sz) { propagate(a); Monoid nxt = type ? f(reflect(2 * a + type), M) : f(M, reflect(2 * a + type)); if(check(nxt)) a = 2 * a + type; else M = nxt, a = 2 * a + 1 - type; } return a - sz; } template< typename C > ll find_first(ll a, const C &check) { Monoid L = M1; if(a <= 0) { if(check(f(L, reflect(1)))) return find_subtree(1, check, L, false); return -1; } thrust(a + sz); ll b = sz; for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) { if(a & 1) { Monoid nxt = f(L, reflect(a)); if(check(nxt)) return find_subtree(a, check, L, false); L = nxt; ++a; } } return -1; } template< typename C > ll find_last(ll b, const C &check) { Monoid R = M1; if(b >= sz) { if(check(f(reflect(1), R))) return find_subtree(1, check, R, true); return -1; } thrust(b + sz - 1); ll a = sz; for(b += sz; a < b; a >>= 1, b >>= 1) { if(b & 1) { Monoid nxt = f(reflect(--b), R); if(check(nxt)) return find_subtree(b, check, R, true); R = nxt; } } return -1; } void print(){ for(ll i=0;i vectorstatic_rectangle_add_rectangle_sum(const vector>&add,const vector>&query){ vectorxc,yc; xc.reserve(add.size()*2+query.size()*2); yc.reserve(add.size()*2+query.size()*2); for(int i=0;impx(xc),mpy(yc); struct M{ V a,b,len; }; using OM=pair; auto f=[&](M x,M y)->M{ return {x.a+y.a,x.b+y.b,x.len+y.len}; }; auto g=[&](M x,OM y)->M{ return {x.a+y.first*x.len,x.b+y.second*x.len,x.len}; }; auto h=[&](OM x,OM y)->OM{ return make_pair(x.first+y.first,x.second+y.second); }; LazySegmentTree seg(mpy.size(),f,g,h,M{0,0,0},OM(0,0)); for(int i=0;i>ga(mpx.size()),gq(mpx.size()); for(int i=0;iret(query.size()); for(int i=0;in(3); rep(i,0,3)cin>>n[i]; int m;cin>>m; vectoru(m),v(m); rep(i,0,m)cin>>u[i]>>v[i],u[i]--,v[i]--; int sn=acc(n); vector>nu(m,MP(-1,-1)),nv(m,MP(-1,-1)); { int pn=0; vectormp(sn); rep(i,0,3){ vectorimos(n[i]+2); auto get=[&](int x){ //cout<<"get" spa x spa sn<r)swap(l,r); //cout<idx(n[i]+2); rep(j,0,n[i]+1)idx[j+1]=idx[j]+(imos[j]==0); //debug(idx); if(idx[0]==idx.back()){ cout<<0<>premx(3); vector>sufmi(3); rep(i,0,3){ premx[i].assign(n[0],0); sufmi[i].assign(n[0],n[i]-1); } rep(i,0,m){ if(nu[i].fi==-1)continue; if(nv[i].fi==0)swap(nu[i],nv[i]); if(nu[i].fi!=0)continue; if(nv[i].fi==0)continue; //cout<>add; vector>query; //debug(premx);cout<lcmi(n[1],n[2]),rcmx(n[1],0); //debug(lcmi); rep(i,0,m){ if(nu[i].fi>nv[i].fi)swap(nu[i],nv[i]); if(nu[i].fi==1&&nv[i].fi==2){ //cout<0)chmin(lcmi[nu[i].se-1],nv[i].se); if(nu[i].se