import sys from collections import deque def main(): input = sys.stdin.read().split() ptr = 0 H = int(input[ptr]) ptr += 1 W = int(input[ptr]) ptr += 1 A = [] for _ in range(H): row = list(map(int, input[ptr:ptr+W])) ptr += W A.append(row) edges = [] for i in range(H): for j in range(W): current = i * W + j if j < W - 1: right = i * W + (j + 1) w = max(A[i][j], A[i][j+1]) edges.append((w, current, right)) if i < H - 1: down = (i + 1) * W + j w = max(A[i][j], A[i+1][j]) edges.append((w, current, down)) edges.sort() size = H * W parent_uf = list(range(size)) rank = [1] * size def find(u): if parent_uf[u] != u: parent_uf[u] = find(parent_uf[u]) return parent_uf[u] mst_edges = [[] for _ in range(size)] for w, u, v in edges: root_u = find(u) root_v = find(v) if root_u != root_v: if rank[root_u] > rank[root_v]: parent_uf[root_v] = root_u else: parent_uf[root_u] = root_v if rank[root_u] == rank[root_v]: rank[root_v] += 1 mst_edges[u].append((v, w)) mst_edges[v].append((u, w)) log_max = 20 depth = [0] * size parent = [-1] * size max_from_parent = [0] * size root = 0 queue = deque([root]) parent[root] = -1 while queue: u = queue.popleft() for v, w in mst_edges[u]: if parent[v] == -1 and v != root: parent[v] = u max_from_parent[v] = w depth[v] = depth[u] + 1 queue.append(v) up = [[-1] * size for _ in range(log_max)] max_edge = [[0] * size for _ in range(log_max)] for u in range(size): up[0][u] = parent[u] max_edge[0][u] = max_from_parent[u] for k in range(1, log_max): for u in range(size): if up[k-1][u] != -1: up[k][u] = up[k-1][up[k-1][u]] max_edge[k][u] = max(max_edge[k-1][u], max_edge[k-1][up[k-1][u]]) else: up[k][u] = -1 max_edge[k][u] = max_edge[k-1][u] Q = int(input[ptr]) ptr += 1 for _ in range(Q): rs = int(input[ptr]) ptr += 1 cs = int(input[ptr]) ptr += 1 rt = int(input[ptr]) ptr += 1 ct = int(input[ptr]) ptr += 1 u = (rs - 1) * W + (cs - 1) v = (rt - 1) * W + (ct - 1) res = 0 du = depth[u] dv = depth[v] u_orig = u v_orig = v if depth[u] < depth[v]: u, v = v, u for k in range(log_max-1, -1, -1): if up[k][u] != -1 and depth[up[k][u]] >= depth[v]: res = max(res, max_edge[k][u]) u = up[k][u] if u == v: print(res) continue for k in range(log_max-1, -1, -1): if up[k][u] != up[k][v]: res = max(res, max_edge[k][u], max_edge[k][v]) u = up[k][u] v = up[k][v] res = max(res, max_edge[0][u], max_edge[0][v]) print(res) if __name__ == "__main__": main()