#include #include #include #include int main() { int H, W; std::cin >> H >> W; std::vector A(H, std::vector(W)); for (auto &r : A) for (int &a : r) std::cin >> a; std::vector> rows, cols; for (int i = 0; i < H; i++) { for (int j = 0; j < W; j++) { if (A[i][j] == 0) continue; rows.emplace_back(i, A[i][j]); cols.emplace_back(j, A[i][j]); } } std::sort(rows.begin(), rows.end()); rows.erase(std::unique(rows.begin(), rows.end()), rows.end()); std::sort(cols.begin(), cols.end()); cols.erase(std::unique(cols.begin(), cols.end()), cols.end()); int R = rows.size(), C = cols.size(); atcoder::mf_graph graph(R + C + 2); int source = R + C, sink = source + 1; for (int i = 0; i < R; i++) graph.add_edge(source, i, 1); for (int i = 0; i < C; i++) graph.add_edge(i + R, sink, 1); for (int i = 0; i < H; i++) { for (int j = 0; j < W; j++) { int r = std::lower_bound(rows.begin(), rows.end(), std::pair{i, A[i][j]}) - rows.begin(); int c = std::lower_bound(cols.begin(), cols.end(), std::pair{j, A[i][j]}) - cols.begin(); graph.add_edge(r, c + R, 1); } } std::cout << graph.flow(source, sink) << std::endl; }