#include #include #include #include #include using namespace std; int dx[8]{-2,-2,-1,-1,1,1,2,2}; int dy[8]{-1,1,-2,2,-2,2,-1,1}; struct disjoint_set { vector p, sz; disjoint_set(int n) { p.assign(n, -1); sz.assign(n, 1); } int find(int x) { return p[x] < 0 ? x : (p[x] = find(p[x])); } int getsz(int x) { return sz[find(x)]; } bool merge(int x, int y) { // x goes to y x = find(x); y = find(y); if(x == y) return false; p[x] = y; sz[y] += sz[x]; return true; } }; const array BAD = {-17, -17}; const int INF = 2e9; array find(const vector>& x, int val) { int lhs = 0; int rhs = x.size()-1; while(lhs <= rhs) { int mid = (lhs+rhs)/2; if(val >= x[mid][0] && val <= x[mid][1]) { return {mid, (val - x[mid][0])%4}; } if(val > x[mid][1]) lhs = mid+1; else { assert(val < x[mid][0]); rhs = mid-1; } } return BAD; } int main() { int n, q; cin >> n >> q; vector> rooks(n); for(auto& x: rooks) cin >> x[0] >> x[1]; vector> xseg, yseg; auto getid = [&](array a, array b) -> int { assert(a != BAD && b != BAD); int comp = a[0] * yseg.size() + b[0]; return 16 * comp + 4 * a[1] + b[1]; }; { vector xs; for(auto x: rooks) xs.push_back(x[0]); sort(xs.begin(), xs.end()); xs.erase(unique(xs.begin(), xs.end()), xs.end()); xseg.push_back({-INF, xs[0]-1}); for(int i = 1; i < xs.size(); i++) { if(xs[i] - xs[i-1] > 1) xseg.push_back({xs[i-1]+1, xs[i]-1}); } xseg.push_back({xs.back()+1, INF}); } { vector ys; for(auto x: rooks) ys.push_back(x[1]); sort(ys.begin(), ys.end()); ys.erase(unique(ys.begin(), ys.end()), ys.end()); yseg.push_back({-INF, ys[0]-1}); for(int i = 1; i < ys.size(); i++) { if(ys[i] - ys[i-1] > 1) yseg.push_back({ys[i-1]+1, ys[i]-1}); } yseg.push_back({ys.back()+1, INF}); } disjoint_set dsu(16 * xseg.size() * yseg.size()); auto explore = [&](int x, int y, int xid, int yid) { array xxa = {xid, (x - xseg[xid][0])%4}; array yya = {yid, (y - yseg[yid][0])%4}; for(int k = 0; k < 8; k++) { int nx = x + dx[k]; int ny = y + dy[k]; array xxb; if(nx >= xseg[xid][0] && nx <= xseg[xid][1]) xxb = {xid, (nx - xseg[xid][0])%4}; else if(nx > xseg[xid][1]) { if(xid + 1 < xseg.size() && nx >= xseg[xid+1][0]) xxb = {xid+1, (nx - xseg[xid+1][0])%4}; else continue; } else if(nx < xseg[xid][0]) { if(xid > 0 && nx <= xseg[xid-1][1]) xxb = {xid-1, (nx - xseg[xid-1][0])%4}; else continue; } else assert(false); array yyb; if(ny >= yseg[yid][0] && ny <= yseg[yid][1]) yyb = {yid, (ny - yseg[yid][0])%4}; else if(ny > yseg[yid][1]) { if(yid + 1 < yseg.size() && ny >= yseg[yid+1][0]) yyb = {yid+1, (ny - yseg[yid+1][0])%4}; else continue; } else if(ny < yseg[yid][0]) { if(yid > 0 && ny <= yseg[yid-1][1]) yyb = {yid-1, (ny - yseg[yid-1][0])%4}; else continue; } else assert(false); dsu.merge(getid(xxa, yya), getid(xxb, yyb)); } }; for(int i = 0; i < xseg.size(); i++) for(int j = 0; j < yseg.size(); j++) { int xsize = xseg[i][1] - xseg[i][0] + 1; int ysize = yseg[i][1] - yseg[i][0] + 1; for(int sx = xseg[i][0]; sx < xseg[i][0] + 4 && sx <= xseg[i][1]; sx++) { for(int sy = yseg[j][0]; sy < yseg[j][0] + 4 && sy <= yseg[j][1]; sy++) { explore(sx, sy, i, j); } } } while(q--) { int xa, ya, xb, yb; cin >> xa >> ya >> xb >> yb; array xxa = find(xseg, xa); array yya = find(yseg, ya); array xxb = find(xseg, xb); array yyb = find(yseg, yb); int lid = getid(xxa, yya); int rid = getid(xxb, yyb); if(lid == rid) cout << (dsu.getsz(lid) > 1) << "\n"; else cout << (dsu.find(lid) == dsu.find(rid)) << "\n"; } }