#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define f first
#define s second
#define mp make_pair
#define chmin(a, b) a = min(a,b)
#define chmax(a, b) a = max(a,b)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define all(x) x.begin(),x.end()
#define v vector
ll sq(ll x) {return x*x;}
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    int n, m, w, h; cin >> n >> m >> w >> h;
    v<pair<pii,int>> trees(n);
    v<int> par(n+4), sz(n+4,1);
    iota(all(par),0);
    F0R(i,n) {cin >> trees[i].f.f >> trees[i].f.s >> trees[i].s;}
    v<pair<int,pii>> edges;
    auto dist = [&](int i, int j) {
        return sqrt(sq(trees[i].f.f-trees[j].f.f)+sq(trees[i].f.s-trees[j].f.s));
    };
    // n: right n+1: top n+2: left n+3: bottom
    F0R(i,n) {
        edges.pb({w-trees[i].f.f-trees[i].s,{i,n}});
        edges.pb({trees[i].f.f-trees[i].s,{i,n+2}});
        edges.pb({trees[i].f.s-trees[i].s,{i,n+3}});
        edges.pb({h-trees[i].f.s-trees[i].s,{i,n+1}});
        FOR(j,i+1,n) {
            edges.pb({dist(i,j)-trees[i].s-trees[j].s,{i,j}});
        }
    }
    sort(all(edges),greater<>());
    v<pair<pii,int>> vis(m);
    F0R(i,m) {cin >> vis[i].f.f >> vis[i].f.s; vis[i].s = i;}
    sort(all(vis));
    v<array<bool,4>> ans(m);
    auto get = [&](auto& get, int x)->int {return par[x]==x ? x : par[x]=get(get,par[x]);};
    auto join = [&](int x, int y) {
        int a = get(get,x), b = get(get,y);
        if (a==b) {return;}
        if (sz[a]<sz[b]) {swap(a,b);}
        par[b] = a; sz[a] += sz[b];
    };
    auto diff = [&](int x, int y) {return get(get,x)!=get(get,y);};
    bool hor = true, ver = true;
    bool tr = true, tl = true, bl = true, br = true;
    F0R(i,m) {
        int idx = vis[i].s, e = --vis[i].f.s;
        while (edges.size() && edges.back().f<2*vis[i].f.f) {
            //if (idx==0) {
            //    cout<<edges.back().f << ' ' << edges.back().s.f << ' ' << edges.back().s.s << '\n';
            //}
            join(edges.back().s.f,edges.back().s.s);
            edges.pop_back();
        }
        hor &= diff(n,n+2); ver &= diff(n+1,n+3);
        tr &= diff(n,n+1); tr &= diff(n+1,n+2);
        bl &= diff(n+2,n+3); br &= diff(n+3,n);
        F0R(j,4) {ans[idx][j] = true;}
        //if (idx==0) {
        //    cout<<ver<<' ';
        //    cout << edges.size() << '\n';
        //}
        if (e==0) {
            ans[idx][1] &= ver&&br && bl;
            ans[idx][2] &= ver&&hor&&tr && bl;
            ans[idx][3] &= hor&&tl && bl;
        } else if (e==1) {
            ans[idx][2] &= hor&&tr && br;
            ans[idx][3] &= hor&&ver&&tl && br;
            ans[idx][0] &= ver&&bl && br;
        } else if (e==2) {
            ans[idx][3] &= ver&&tl && tr;
            ans[idx][0] &= hor&&ver&&bl && tr;
            ans[idx][1] &= hor&&br && tr;
        } else if (e==3) {
            ans[idx][0] &= hor&&bl && tl;
            ans[idx][1] &= hor&&ver&&br && tl;
            ans[idx][2] &= ver&&tr && tl;
        }
    }
    F0R(i,m) {
        F0R(j,4) {
            if (ans[i][j]) {cout << j+1;}
        } cout << '\n';
    }
    
    /*
    draw edge centers at circles
    get to exit if set of <2r edges does not block off that line segment i.e
    chain of line segments for borders
    store borders as nodes, circles as nodes, connect with dsu in increasing order
    of radii, add edges when necessary
    connect with dsu, check if sides are connected, blah
    */
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |