## https://yukicoder.me/problems/no/2786 class UnionFind: """ UnionFindの基本的な処理を実装したクラス """ def __init__(self, size): self.root = [i for i in range(size)] self.size = [1] * size def get_root(self, v): if v == self.root[v]: return v else: old_root = self.root[v] new_root = self.get_root(old_root) self.root[v] = new_root return new_root def merge(self, u, v): root_u = self.get_root(u) root_v = self.get_root(v) if root_u == root_v: return False if self.size[root_u] >= self.size[root_v]: self.size[root_u] += self.size[root_v] self.root[root_v] = root_u self.root[v] = root_u else: self.size[root_v] += self.size[root_u] self.root[root_u] = root_v self.root[u] = root_v return True def main(): H, W = map(int, input().split()) A = [] for _ in range(H): A.append(list(map(int, input().split()))) Q = int(input()) queries = [] for _ in range(Q): rs, cs, rt, ct = map(int, input().split()) queries.append((rs - 1, cs - 1, rt - 1, ct - 1)) # コスト単位 array = [[] for _ in range(H * W + 1)] for h in range(H): for w in range(W): array[A[h][w]].append(h * W + w) answers = [-1] * Q st_sets = [set() for _ in range(H * W)] for i in range(Q): rs, cs, rt, ct = queries[i] st_sets[rs * W + cs].add(i) st_sets[rt * W + ct].add(i) uf = UnionFind(H * W) for a in range(H * W + 1): for index in array[a]: h = index // W w = index % W for dh, dw in ((1, 0), (-1, 0), (0, 1), (0, -1)): new_h = dh + h new_w = dw + w if 0 <= new_h < H and 0 <= new_w < W: if A[new_h][new_w] <= a: new_index = new_h * W + new_w r_index = uf.get_root(index) r_new_index = uf.get_root(new_index) if r_index != r_new_index: t_set = None if len(st_sets[r_new_index]) >= len(st_sets[r_index]): for y_index in st_sets[r_index]: if y_index not in st_sets[r_new_index]: st_sets[r_new_index].add(y_index) else: st_sets[r_new_index].remove(y_index) answers[y_index] = a t_set = st_sets[r_new_index] else: for y_index in st_sets[r_new_index]: if y_index not in st_sets[r_index]: st_sets[r_index].add(y_index) else: st_sets[r_index].remove(y_index) answers[y_index] = a t_set = st_sets[r_index] uf.merge(index, new_index) index1 = uf.get_root(index) if index1 == r_index: st_sets[r_index] = t_set else: st_sets[r_new_index] = t_set for i in range(Q): print(answers[i]) if __name__ == "__main__": main()