import sys from collections import deque class Edge: def __init__(self, to, rev, capacity): self.to = to self.rev = rev self.capacity = capacity class Dinic: def __init__(self, n): self.size = n self.graph = [[] for _ in range(n)] def add_edge(self, fr, to, cap): forward = Edge(to, len(self.graph[to]), cap) backward = Edge(fr, len(self.graph[fr]), 0) self.graph[fr].append(forward) self.graph[to].append(backward) def bfs_level(self, s, t, level): q = deque() level[:] = [-1] * self.size level[s] = 0 q.append(s) while q: v = q.popleft() for edge in self.graph[v]: if edge.capacity > 0 and level[edge.to] == -1: level[edge.to] = level[v] + 1 q.append(edge.to) if edge.to == t: return def dfs_flow(self, v, t, flow, level, ptr): if v == t: return flow while ptr[v] < len(self.graph[v]): edge = self.graph[v][ptr[v]] if edge.capacity > 0 and level[v] < level[edge.to]: pushed = self.dfs_flow(edge.to, t, min(flow, edge.capacity), level, ptr) if pushed > 0: edge.capacity -= pushed self.graph[edge.to][edge.rev].capacity += pushed return pushed ptr[v] += 1 return 0 def max_flow(self, s, t): flow = 0 level = [-1] * self.size while True: self.bfs_level(s, t, level) if level[t] == -1: return flow ptr = [0] * self.size pushed = self.dfs_flow(s, t, float('inf'), level, ptr) while pushed > 0: flow += pushed pushed = self.dfs_flow(s, t, float('inf'), level, ptr) level = [-1] * self.size class NodeAssigner: def __init__(self, H, W): self.H = H self.W = W self.node_count = 2 # S=0, T=1 self.in_node = {} self.out_node = {} # Row 1 for j in range(1, W + 1): node = self.node_count self.in_node[(1, j)] = node self.out_node[(1, j)] = node self.node_count += 1 # Rows 2 to H-1 for i in range(2, H): for j in range(1, W + 1): in_node = self.node_count self.node_count += 1 out_node = self.node_count self.node_count += 1 self.in_node[(i, j)] = in_node self.out_node[(i, j)] = out_node # Row H for j in range(1, W + 1): node = self.node_count self.in_node[(H, j)] = node self.out_node[(H, j)] = node self.node_count += 1 def get_in_node(self, i, j): return self.in_node[(i, j)] def get_out_node(self, i, j): return self.out_node[(i, j)] def main(): H, W = map(int, sys.stdin.readline().split()) A_rows = H - 2 A = [] for _ in range(H - 2): A.append(list(map(int, sys.stdin.readline().split()))) INF = 1 << 60 assigner = NodeAssigner(H, W) dinic = Dinic(assigner.node_count) # Add edges for split nodes (in -> out) for i in range(2, H): for j in range(1, W + 1): # row in A is i-2 (since A is rows 2 to H-1) a = A[i - 2][j - 1] in_node = assigner.get_in_node(i, j) out_node = assigner.get_out_node(i, j) if a == -1: capacity = INF else: capacity = a dinic.add_edge(in_node, out_node, capacity) directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] for i in range(1, H + 1): for j in range(1, W + 1): for di, dj in directions: ni, nj = i + di, j + dj if 1 <= ni <= H and 1 <= nj <= W: from_out = assigner.get_out_node(i, j) to_in = assigner.get_in_node(ni, nj) dinic.add_edge(from_out, to_in, INF) # Reverse edge is automatically added with 0 capacity # Connect S to first row for j in range(1, W + 1): in_node = assigner.get_in_node(1, j) dinic.add_edge(0, in_node, INF) # Connect last row to T for j in range(1, W + 1): out_node = assigner.get_out_node(H, j) dinic.add_edge(out_node, 1, INF) max_flow = dinic.max_flow(0, 1) if max_flow >= INF: print(-1) else: print(max_flow) if __name__ == '__main__': main()