#include #include #include #include using namespace std; struct ragetree { vector>> tree; int SZ; ragetree(int n) { SZ = 1; while(SZ < n) SZ *= 2; tree.resize(2*SZ); } void ins(int x, int y, int v) { x += SZ; while(x) { tree[x].emplace_back(y, v); x /= 2; } } void finalize() { for(int i = 2*SZ-1; i > 0; i--) { if(tree[i].size() > 1) sort(tree[i].begin(), tree[i].end()); } } void _upd(const vector>& v, int ya, int yb, vector& ret) { if(ret.size() >= 45) return; auto it = lower_bound(v.begin(), v.end(), make_pair(ya, 0)); while(it != v.end() && it->first <= yb) { ret.push_back(it->second); if(ret.size() >= 45) return; it++; } } void qry(int lhs, int rhs, int ya, int yb, vector& ret) { lhs += SZ; rhs += SZ; while(lhs <= rhs) { if(lhs%2) _upd(tree[lhs++], ya, yb, ret); if(rhs%2==0) _upd(tree[rhs--], ya, yb, ret); lhs /= 2; rhs /= 2; } } }; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n, q; cin >> n >> q; vector> v(n); vector xv(n); { for(int i = 0; i < n; i++) { cin >> v[i][0] >> v[i][1] >> v[i][2]; xv[i] = v[i][0]; } sort(xv.begin(), xv.end()); xv.erase(unique(xv.begin(), xv.end()), xv.end()); for(int i = 0; i < n; i++) { v[i][0] = lower_bound(xv.begin(), xv.end(), v[i][0]) - xv.begin(); } } ragetree rt(xv.size()); for(int i = 0; i < n; i++) rt.ins(v[i][0], v[i][1], v[i][2]); rt.finalize(); while(q--) { int xa, ya, xb, yb; cin >> xa >> ya >> xb >> yb; xa = lower_bound(xv.begin(), xv.end(), xa) - xv.begin(); xb = upper_bound(xv.begin(), xv.end(), xb) - xv.begin() - 1; vector cand; rt.qry(xa, xb, ya, yb, cand); if(cand.size() == 45) { cout << "1\n"; continue; } sort(cand.begin(), cand.end()); int ret = 0; for(int i = 2; i < cand.size() && ret == 0; i++) ret = cand[i] < cand[i-1] + cand[i-2]; cout << ret << "\n"; } }