#include #include #include #include #include #include #include #include #include #include #include #define fr(i,n) for(i=0;i<(int)(n);i++) #define fit(a,b) for(typeof(b.begin()) a = b.begin(); a != b.end(); a++) #define pb push_back #define MP make_pair #define F first #define S second #define SZ(u) ((int)u.size()) #define WT(x) cout << #x << ": " << x << endl using namespace std; typedef long long ll; typedef pair p2; typedef vector vi; int N, Dx, Dy, Q, M; int X[600000], Y[600000]; int Max[5000000], Tree[5000000], P; vi Points; map idx_map; void init(vector > &rects) { set pt; int i; fr (i, SZ(rects)) { pt.insert(rects[i].S.F); pt.insert(rects[i].S.S); } Points.clear(); idx_map.clear(); i = 0; for (set::iterator it = pt.begin(); it != pt.end(); it++) { Points.pb(*it); idx_map[*it] = i++; } P = 1; while (P < SZ(pt)) P *= 2; for (i = P * 2 - 1; i >= 0; i--) Max[i] = Tree[i] = 0; } void update(int sv, int ev, int plus) { int st = P + idx_map[sv]; int en = P + idx_map[ev]; Tree[st] += plus; Max[st] = Tree[st]; if (en != st) Tree[en] += plus; Max[en] = Tree[en]; while (st != 1) { if (st % 2 == 0 && st + 1 < en) { Tree[st+1] += plus; Max[st+1] += plus; } if (en % 2 == 1 && en - 1 > st) { Tree[en-1] += plus; Max[en-1] += plus; } st /= 2, en /= 2; Max[st] = Tree[st] + max(Max[st * 2], Max[st * 2 + 1]); Max[en] = Tree[en] + max(Max[en * 2], Max[en * 2 + 1]); } } void get_ans(int u, int &ans_x, int &ans_y, int &ans) { int idx = 1, aim = Max[1]; while (idx < P) { if (Max[idx * 2] >= Max[idx * 2 + 1]) idx = idx * 2; else idx = idx * 2 + 1; } int v = Points[idx - P]; int x = (u - v) / 2, y = (u + v) / 2; if (y <= 0) x -= (1 - y), y = 1; if (y > Dy) x += (y - Dy), y = Dy; if (x <= 0) x = 1; if (x > Dx) x = Dx; if (aim > ans || (aim == ans && y < ans_y) || (aim == ans && y == ans_y && x < ans_x)) { ans = aim; ans_x = x, ans_y = y; } } int main() { int case_num = 0, i, j; while (scanf("%d%d%d%d", &Dx, &Dy, &N, &Q) == 4) { if (Dx == 0) break; case_num++; fr (i, N) scanf("%d%d", &X[i], &Y[i]); fr (i, Q) { scanf("%d", &M); int ans_x = 1, ans_y = 1, ans = 0; for (int plus = 0; plus < 2; plus++) { vector > rects; fr (j, N) { int us, ue, vs, ve; us = X[j] + Y[j] - M; if (abs(us) % 2 != plus % 2) us++; ue = X[j] + Y[j] + M; if (abs(ue) % 2 != plus % 2) ue--; vs = Y[j] - X[j] - M; if (abs(vs) % 2 != plus % 2) vs++; ve = Y[j] - X[j] + M; if (abs(ve) % 2 != plus % 2) ve--; if (us <= ue && vs <= ve) { rects.pb(MP(MP(us, ue), MP(vs, ve))); } } if (SZ(rects) == 0) continue; sort(rects.begin(), rects.end()); set > ends; j = 0; init(rects); while (j < SZ(rects) || SZ(ends)) { int u; if (SZ(ends) == 0 || (j < SZ(rects) && rects[j].F.F <= ends.begin()->F)) { update(rects[j].S.F, rects[j].S.S, 1); get_ans(rects[j].F.F, ans_x, ans_y, ans); ends.insert(MP(rects[j].F.S, MP(rects[j].S.F, rects[j].S.S))); j++; } else { update(ends.begin()->S.F, ends.begin()->S.S, -1); ends.erase(ends.begin()); } } } if (i == 0) printf("Case %d:\n", case_num); printf("%d (%d,%d)\n", ans, ans_x, ans_y); } } return 0; }