#nullable enable #region var (_input, _iter) = (Array.Empty(), 0); T I() where T : IParsable { while (_iter >= _input.Length) (_input, _iter) = (Console.ReadLine()!.Trim().Split(' '), 0); return T.Parse(_input[_iter++], null); } #endregion static T[] Range(int n, Func F) => Enumerable.Range(0, n).Select(_ => F()).ToArray(); const int Max = int.MaxValue / 2; var h = I(); var w = I(); var (sx, sy) = (I(), I()); var g = new bool[h + 2, w + 2]; for (var i = 0; i < h; i++) { var row = I(); for (var j = 0; j < w; j++) g[i + 1, j + 1] = row[j] == '.'; } var qz = Range(I(), () => (I(), I(), I())); var dists1 = new int[h + 2, w + 2]; var dists2 = new int[h + 2, w + 2]; var dirs1 = new bool[h + 2, w + 2, 3, 3]; var dirs2 = new bool[h + 2, w + 2, 3, 3]; for (var i = 1; i <= h; i++) for (var j = 1; j <= w; j++) dists1[i, j] = dists2[i, j] = Max; dists1[sx, sy] = 0; var q = new Queue<(int, int, int)>(); q.Enqueue((sx, sy, 0)); while (q.Count > 0) { var (qx, qy, qd) = q.Dequeue(); if (qd > dists2[qx, qy]) continue; var nd = qd + 1; for (var dx = -1; dx <= 1; dx++) for (var dy = -1; dy <= 1; dy++) { if ((dx, dy) == (0, 0)) continue; var (x, y) = (qx, qy); while (true) { x += dx; y += dy; if (!g[x, y]) break; if (dists1[x, y] > nd) { dists1[x, y] = nd; q.Enqueue((x, y, nd)); dirs1[x, y, dx + 1, dy + 1] = true; } else if (dists1[x, y] < nd && dists2[x, y] > nd) { dists2[x, y] = nd; q.Enqueue((x, y, nd)); dirs2[x, y, dx + 1, dy + 1] = true; } else if (dists1[x, y] == nd && dirs1[x, y, dx + 1, dy + 1]) { break; } else if (dists2[x, y] == nd && dirs2[x, y, dx + 1, dy + 1]) { break; } } } } var ans = new List(); foreach (var (x, y, t) in qz) { var dq1 = dists1[x, y]; var dq2 = dists2[x, y]; if (t >= dq1 && (t - dq1) % 2 == 0 && ((x, y) != (sx, sy) || dq2 < Max)) ans.Add("Yes"); else if (t >= dq2 && (t - dq2) % 2 == 0) ans.Add("Yes"); else ans.Add("No"); } Console.WriteLine(string.Join(Environment.NewLine, ans));