#define PROBLEM "https://judge.yosupo.jp/problem/rectangle_sum"
#include<bits/stdc++.h>#define REP(i, n) for (int i = 0; i < (n); i++)
#include"library/datastructure/CumulativeSum.hpp"
#include"library/datastructure/WaveletMatrix.hpp"
#include"library/r2/Projection.hpp"
#include"library/r2/XY.hpp"usingll=longlong;usingr2=XY<ll>;intmain(){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);intn,q;std::cin>>n>>q;std::vector<r2>r2s(n);std::vector<int>x(n),y(n),w(n);REP(i,n){std::cin>>x[i]>>y[i]>>w[i];r2s[i]=r2(x[i],y[i]);}autoP=Projection(r2s);std::vector<int>Y(P.size(),0);REP(id,P.size())Y[id]=P.r(id).y;WaveletMatrixWM(Y);intLOG=WM.height();std::vectorW(LOG,std::vector<ll>(P.size(),0));REP(i,n){intidx=P.id(x[i],y[i]);autoidxs=WM.points(idx);REP(h,LOG)W[h][idxs[h]]+=w[i];}std::vector<CumulativeSum<ll>>C(LOG);REP(h,LOG)C[h]=CumulativeSum<ll>(W[h]);REP(j,q){intl,r,d,u;std::cin>>l>>d>>r>>u;auto[L,R]=P.interval(l,r);llres=0;autointervals=WM.intervals(L,R,u);for(constauto&[h,l,r]:intervals)res+=C[h].sum(l,r);autointervals2=WM.intervals(L,R,d);for(constauto&[h,l,r]:intervals2)res-=C[h].sum(l,r);std::cout<<res<<"\n";}}
#line 1 "test/library-checker/DataStructure/RectangleSum_2.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/rectangle_sum"
#include<bits/stdc++.h>#define REP(i, n) for (int i = 0; i < (n); i++)
#line 1 "library/datastructure/CumulativeSum.hpp"
template<typenameT>structCumulativeSum{usingU=std::conditional_t<std::is_same_v<T,int>,longlong,T>;std::vector<U>A;CumulativeSum():A(1,0){}CumulativeSum(conststd::vector<T>&v):A(v.size()+1,0){for(inti=0;i<v.size();i++)A[i+1]=A[i]+v[i];}voidadd(constT&a){A.push_back(A.back()+a);}Usum(intl,intr){assert(0<=landl<=randr<A.size());returnA[r]-A[l];}Usum(){returnA.back();}};#line 4 "library/datastructure/FullyIndexableDictionary.hpp"
classFullyIndexableDictionary{intn,block;// 64個事に区切ったブロックの個数std::vector<unsignedlonglong>bit;std::vector<unsignedint>sum;// ブロック毎の累積和boolprepared;public:FullyIndexableDictionary(){}FullyIndexableDictionary(intn):n(n),block((n+63)>>6),bit(block,0),sum(block+1,0),prepared(false){}boolis_prepared(){returnprepared;}voidset(intk){bit[k>>6]|=1ull<<(k&63);sum[(k>>6)+1]++;}voidbuild(){assert(!prepared);prepared=true;for(inti=0;i<block;i++)sum[i+1]+=sum[i];}booloperator[](intk)const{returnbool((bit[k>>6]>>(k&63))&1);}// [0,j) の合計intrank(intj,boolf=1){assert(prepared);inta=sum[j>>6]+__builtin_popcountll(bit[j>>6]&((1ull<<(j&63))-1));return(f?a:j-a);}// 0-indexed で k 番目の f の場所intselect(intk,boolf=1){assert(prepared);if(k<0orrank(n,f)<=k)return-1;intl=0,r=n;while(r-l>1){intm=(l+r)>>1;(rank(m,f)>=k+1?r:l)=m;}returnr-1;}// l以上で k 番目の f の場所intselect(intk,boolf,intl){returnselect(rank(l,f)+k,f);}};#line 2 "library/util/Compress.hpp"
template<typenameT,boolSentinel=false>classCompress{std::vector<T>v;boolprepared;public:Compress():prepared(false){ifconstexpr(Sentinel){static_assert(std::numeric_limits<T>::is_specialized,"cannot use Sentinel");v={std::numeric_limits<T>::min(),std::numeric_limits<T>::max()};}}Compress(conststd::vector<T>&w):v(w),prepared(false){ifconstexpr(Sentinel){static_assert(std::numeric_limits<T>::is_specialized,"cannot use Sentinel");v.push_back(std::numeric_limits<T>::min());v.push_back(std::numeric_limits<T>::max());}build();}voidadd(Ta){assert(!prepared);v.push_back(a);}voidbuild(){assert(!prepared);prepared=true;std::ranges::sort(v);autoresult=std::ranges::unique(v);v.erase(result.begin(),result.end());}boolis_prepared()const{returnprepared;}intoperator[](constT&a)const{assert(prepared);autoit=std::ranges::lower_bound(v,a);assert(*it==a);returnstd::distance(v.begin(),it);}intgeq(constT&a)const{assert(prepared);autoit=std::ranges::lower_bound(v,a);returnstd::distance(v.begin(),it);}intgt(constT&a)const{assert(prepared);autoit=std::ranges::upper_bound(v,a);returnstd::distance(v.begin(),it);}intleq(constT&a)const{assert(prepared);autoit=--std::ranges::upper_bound(v,a);returnstd::distance(v.begin(),it);}intlt(constT&a)const{assert(prepared);autoit=--std::ranges::lower_bound(v,a);returnstd::distance(v.begin(),it);}Tr(intid)const{assert(prepared);returnv[id];}boolexist(constT&a)const{assert(prepared);return(*std::ranges::lower_bound(v,a))==a;}intsize()const{returnv.size();}Tmax()const{returnv.back();}Tmin()const{returnv[0];}friendstd::ostream&operator<<(std::ostream&os,constCompress&C){for(inti=0;i<C.v.size();i++)os<<C.v[i]<<":"<<i<<" ";returnos;}};#line 4 "library/datastructure/WaveletMatrix.hpp"
#define REP_(i, n) for (int i = 0; i < (n); i++)
template<typenameT,boolCOMPRESS=true>classWaveletMatrix{protected:usingU=std::conditional_t<COMPRESS,int,T>;static_assert(std::is_integral_v<U>,"Wavelet Matrix is only for integer");intn,memo,log;std::vector<FullyIndexableDictionary>mat;std::vector<int>zero_cnt;Compress<T,true>C;std::vector<T>data;constexprUcomp(constT&x)const{ifconstexpr(COMPRESS){returnC.geq(x);}else{returnx;}}constexprTuncomp(constU&a){ifconstexpr(COMPRESS){returnC.r(a);}else{returna;}}// 0-indexed で下から i bit 目inlineboollow_bit(constU&a,inti)const{return(a>>i)&1;}// 0-indexed で上から i bit 目inlineboolhigh_bit(constU&a,inti)const{returnlow_bit(a,log-i-1);}intnxt(intidx,inth,constU&a){// idx の位置に a があった場合上から h bit 目でどこに行くかboolbit=high_bit(a,h);returnmat[h].rank(idx,bit)+(bit?zero_cnt[h]:0);}public:WaveletMatrix(std::vector<T>v,intlog_=0):n(v.size()),data(v),log(log_){std::vector<U>cv(n);ifconstexpr(COMPRESS){C=Compress<T,true>(v);for(inti=0;i<n;i++)cv[i]=C[v[i]];while(C.size()>=(1ull<<log))log++;}else{cv=v;Tmx=0;for(constT&a:v){assert(a>=0);if(mx<a)mx=a;}while(mx>=(1ull<<log))log++;}mat.resize(log);zero_cnt.resize(log);std::vector<U>lv(n),rv(n);REP_(h,log){mat[h]=FullyIndexableDictionary(n);intl=0,r=0;REP_(i,n)if(high_bit(cv[i],h)){rv[r++]=cv[i];mat[h].set(i);}elselv[l++]=cv[i];zero_cnt[h]=l;mat[h].build();std::swap(lv,cv);REP_(i,r)cv[l+i]=rv[i];}}// [l,r) の x の個数intrank(intl,intr,constT&x){ifconstexpr(COMPRESS){if(!C.exist(x))return0;}Ua=comp(x);REP_(h,log){l=nxt(l,h,a);r=nxt(r,h,a);}memo=l;returnr-l;}intrank(intr,constT&x){returnrank(x,0,r);}// k 番目の x の indexintselect(intk,constT&x){Ua=comp(x);if(rank(a,n)<k)return-1;k+=memo;for(inth=log-1;h>=0;h--){boolbit=high_bit(a,h);if(bit)k-=zero_cnt[h];k=mat[h].select(k,bit);}returnk;}// [l,r) で 0-indexed k 番目に大きい値Tkth_largest(intl,intr,intk){if(k<0orr-l<=k)return-1;Ures=0;REP_(h,log){intL=mat[h].rank(l);intR=mat[h].rank(r);res<<=1;if(R-L>k){l=L+zero_cnt[h];r=R+zero_cnt[h];res++;}else{k-=R-L;l-=L;r-=R;}}returnuncomp(res);}Tkth_smallest(intl,intr,intk){returnkth_largest(l,r,r-l-k-1);}// [l,r) で x 未満の個数intrange_freq(intl,intr,constT&upper){Ua=comp(upper);intres=0;REP_(h,log){if(high_bit(a,h)){intL=mat[h].rank(l,0),R=mat[h].rank(r,0);res+=R-L;}l=nxt(l,h,a);r=nxt(r,h,a);}returnres;}// [l,r) で [lower,upper) の個数intrange_freq(intl,intr,constT&lower,constT&upper){returnrange_freq(l,r,upper)-range_freq(l,r,lower);}std::optional<T>lt(intl,intr,constT&x){intcnt=range_freq(l,r,x);if(cnt)returnkth_smallest(l,r,cnt-1);returnstd::nullopt;}std::optional<T>leq(intl,intr,constT&x){if(rank(l,r,x))returnx;returnlt(l,r,x);}std::optional<T>geq(intl,intr,constT&x){intcnt=r-l-range_freq(l,r,x);if(cnt)returnkth_largest(l,r,cnt-1);returnstd::nullopt;}std::optional<T>gt(intl,intr,constT&x){Ty;ifconstexpr(COMPRESS){y=C.r(C.gt(x));}else{y=x+1;}returngeq(l,r,y);}// セグ木などを載せる時用// BIT は専用のライブラリを作ってあるが、一応抽象化も持っておく// 構築したものを返してるので遅そうintheight()const{returnlog;}std::vector<int>points(intidx){std::vector<int>res(log);Ua=comp(data[idx]);REP_(h,log){idx=nxt(idx,h,a);res[h]=idx;}returnres;}std::vector<std::tuple<int,int,int>>intervals(intl,intr,constT&upper){std::vector<std::tuple<int,int,int>>res;Ua=comp(upper);REP_(h,log){if(high_bit(a,h)){intL=mat[h].rank(l,0),R=mat[h].rank(r,0);res.emplace_back(h,L,R);}l=nxt(l,h,a);r=nxt(r,h,a);}returnres;}std::vector<std::tuple<int,int,int>>kth_largest_intervals(intl,intr,intk){assert(0<=kandk<r-l);std::vector<std::tuple<int,int,int>>res;REP_(h,log){intL=mat[h].rank(l);intR=mat[h].rank(r);if(R-L>k){l=L+zero_cnt[h];r=R+zero_cnt[h];}else{res.emplace_back(h,L+zero_cnt[h],R+zero_cnt[h]);k-=R-L;l-=L;r-=R;}}returnres;}std::vector<std::tuple<int,int,int>>kth_smallest_intervals(intl,intr,intk){returnkth_largest_intervals(l,r,r-l-k-1);}};#undef REP_
#line 2 "library/r2/XY.hpp"
template<typenameT>structXY{Tx,y;XY()=default;XY(Tx,Ty):x(x),y(y){}XY(conststd::pair<T,T>&xy):x(xy.first),y(xy.second){}XYoperator+()const{return*this;}XYoperator-()const{returnXY(-x,-y);}XY&operator++(){x++;y++;return*this;}XY&operator--(){x--;y--;return*this;}XY&operator++(int){XYa=*this;++*this;returna;}XY&operator--(int){XYa=*this;--*this;returna;}XY&operator+=(constXY&v){x+=v.x;y+=v.y;return*this;}XY&operator-=(constXY&v){x-=v.x;y-=v.y;return*this;}XY&operator*=(constT&a){x*=a;y*=a;return*this;}XY&operator/=(constT&a){x/=a;y/=a;return*this;}friendXYoperator+(constXY&u,constXY&v){returnXY(u)+=v;}friendXYoperator-(constXY&u,constXY&v){returnXY(u)-=v;}friendXYoperator*(constXY&u,constT&a){returnXY(u)*=a;}friendXYoperator*(constT&a,constXY&u){returnXY(u)*=a;}friendXYoperator/(constXY&u,constT&a){returnXY(u)/=a;}booloperator<(constXY&v)const{returnx!=v.x?x<v.x:y<v.y;}booloperator>(constXY&v)const{returnx!=v.x?x>v.x:y>v.y;}booloperator==(constXY&v)const{returnx==v.xandy==v.y;}booloperator<=(constXY&v)const{return!(*this>v);}booloperator>=(constXY&v)const{return!(*this<v);}booloperator!=(constXY&v)const{return!(*this==v);}doublearg()const{returnatan2(y,x);}// [0,2pi) で θ(u)<θ(v) の時 true// (0,0) は 2pi に相当// static bool angle_cmp(const XY&u,const XY&v){// using U=conditional_t< is_same_v<T,int>,long long,T>;// if(u==XY(0,0))return false;// if(v==XY(0,0))return true;// if(u.y==0){// if(u.x>0)return true;// if(v.y==0)return v.x<0;// return v.y<0;// }// if(u.y>0){// if(v.y==0)return v.x<0;// if(v.y<0)return true;// return U(v.x)*u.y <= U(u.x)*v.y;// }// if(v.y>=0)return false;// return U(v.x)*u.y <= U(u.x)*v.y;//}friendTdot(constXY&u,constXY&v){returnu.x*v.x+u.y*v.y;}Tnorm(){returndot(*this,*this);}Tabs(){returnsqrt(norm());}friendstd::istream&operator>>(std::istream&is,XY&v){is>>v.x>>v.y;returnis;}friendstd::ostream&operator<<(std::ostream&os,constXY&v){os<<v.x<<" "<<v.y;returnos;}staticXYdirection(constchar&c){if(c=='R')return{1,0};if(c=='L')return{-1,0};if(c=='U')return{0,-1};if(c=='D')return{0,1};return{0,0};}};#line 4 "library/r2/Projection.hpp"
template<typenameT>classProjection{usingr2=XY<T>;Compress<r2>C;public:Projection(conststd::vector<r2>&v):C(v){}intsize(){returnC.size();}intid(r2xy){returnC[xy];}intid(intx,inty){returnC[r2(x,y)];}r2r(intid){returnC.r(id);}//[l,r) を返すstd::pair<int,int>interval(constT&l,constT&r){if(C.max().x<lorr<=C.min().x)returnstd::make_pair(0,0);Tmn=std::numeric_limits<T>::min();intL=C.geq(r2(l,mn));intR=C.geq(r2(r,mn));returnstd::make_pair(L,R);}};#line 10 "test/library-checker/DataStructure/RectangleSum_2.test.cpp"
usingll=longlong;usingr2=XY<ll>;intmain(){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);intn,q;std::cin>>n>>q;std::vector<r2>r2s(n);std::vector<int>x(n),y(n),w(n);REP(i,n){std::cin>>x[i]>>y[i]>>w[i];r2s[i]=r2(x[i],y[i]);}autoP=Projection(r2s);std::vector<int>Y(P.size(),0);REP(id,P.size())Y[id]=P.r(id).y;WaveletMatrixWM(Y);intLOG=WM.height();std::vectorW(LOG,std::vector<ll>(P.size(),0));REP(i,n){intidx=P.id(x[i],y[i]);autoidxs=WM.points(idx);REP(h,LOG)W[h][idxs[h]]+=w[i];}std::vector<CumulativeSum<ll>>C(LOG);REP(h,LOG)C[h]=CumulativeSum<ll>(W[h]);REP(j,q){intl,r,d,u;std::cin>>l>>d>>r>>u;auto[L,R]=P.interval(l,r);llres=0;autointervals=WM.intervals(L,R,u);for(constauto&[h,l,r]:intervals)res+=C[h].sum(l,r);autointervals2=WM.intervals(L,R,d);for(constauto&[h,l,r]:intervals2)res-=C[h].sum(l,r);std::cout<<res<<"\n";}}