import sys sys.setrecursionlimit(10**6) from collections import deque class HopcroftKarp: def __init__(self, N1, N2): self.N1 = N1 self.N2 = N2 self.G = [[] for _ in range(self.N1+1)] self.pair1 = [0]*(self.N1+1) self.pair2 = [0]*(self.N2+1) self.matching_size = -1 def add_edge(self, fr, to): self.G[fr].append(to) def bfs(self): que = deque() for i in range(1, self.N1+1): if self.pair1[i] == 0: self.dist[i] = 0 que.append(i) else: self.dist[i] = INF self.dist[0] = INF while que: n = que.popleft() if self.dist[n] < self.dist[0]: for v in self.G[n]: if self.dist[self.pair2[v]] == INF: self.dist[self.pair2[v]] = self.dist[n]+1 que.append(self.pair2[v]) return self.dist[0] != INF def dfs(self, n): if n != 0: for v in self.G[n]: if self.dist[self.pair2[v]] == self.dist[n]+1: if self.dfs(self.pair2[v]): self.pair2[v] = n self.pair1[n] = v return True self.dist[n] = INF return False return True def flow(self): if self.matching_size != -1: return self.matching_size self.dist = [0]*(self.N1+1) ans = 0 while self.bfs(): for i in range(1, self.N1+1): if self.pair1[i] == 0 and self.dfs(i): ans += 1 self.matching_size = ans return ans def get_matching(self): if self.matching_size == -1: self.flow() ans = [] for i in range(1, self.N1+1): if self.pair1[i] != 0: ans.append((i, self.pair1[i])) return ans def minimum_vertex_cover(self): if self.matching_size == -1: self.flow() return self.matching_size def maximum_independent_set(self): return self.N1+self.N2-self.minimum_vertex_cover() def minimum_edge_cover(self): F = [False]*(self.N1+self.N2+1) for n in range(1, self.N1+1): F[n] = True for v in self.G[n]: F[self.N1+v] = True if sum(F) < self.N1+self.N2: return -1 if self.matching_size == -1: self.flow() return self.N1+self.N2-self.matching_size def preparation(self): if self.matching_size == -1: self.flow() L = self.N1+self.N2 G = [[] for _ in range(L+1)] for n in range(1, self.N1+1): for v in self.G[n]: if self.pair1[n] == v: G[self.N1+v].append(n) else: G[n].append(self.N1+v) visited = [False]*(L+1) que = deque() for i in range(1, self.N1+1): if self.pair1[i] == 0: visited[i] = True que.append(i) while que: n = que.popleft() for v in G[n]: if not visited[v]: visited[v] = True que.append(v) return visited def get_minimum_vertex_cover(self): visited = self.preparation() ans1 = [] ans2 = [] for i in range(1, self.N1+self.N2+1): if i <= self.N1 and not visited[i]: ans1.append(i) elif self.N1+1 <= i and visited[i]: ans2.append(i-self.N1) return ans1, ans2 def get_maximum_independent_set(self): visited = self.preparation() ans1 = [] ans2 = [] for i in range(1, self.N1+self.N2+1): if i <= self.N1 and visited[i]: ans1.append(i) elif self.N1+1 <= i and not visited[i]: ans2.append(i-self.N1) return ans1, ans2 def get_minimum_edge_cover(self): cnt = self.minimum_edge_cover() if cnt == -1: return None ans = [] pair = [-1]*(self.N1+self.N2+1) for n in range(1, self.N1+1): pair[n] = self.G[n][0] for v in self.G[n]: if pair[self.N1+v] == -1: pair[self.N1+v] = n for i in range(1, self.N1+self.N2+1): if i <= self.N1 and self.pair1[i] != 0: ans.append((i, self.pair1[i])) elif i <= self.N1 and self.pair1[i] == 0: ans.append((i, pair[i])) elif self.N1+1 <= i and self.pair2[i-self.N1] == 0: ans.append((pair[i], i-self.N1)) return ans INF = 1<<60 N, M = map(int, input().split()) A = [list(map(int, input().split())) for _ in range(N)] B = list(map(list, zip(*A))) if any(sum(a) != M for a in A) or any(sum(b) != M for b in B): exit(print(-1)) ans = [] for _ in range(M): H = HopcroftKarp(N, N) for i in range(N): for j in range(N): if A[i][j]: H.add_edge(i+1, j+1) matching = H.get_matching() res = [-1]*N for a, b in matching: a, b = a-1, b-1 res[a] = b+1 A[a][b] -= 1 ans.append(res) for a in ans: print(*a)