#include #include #include #include #include #include #include using std::cin; using std::cout; const char endl = '\n'; const int N = 55, M = (N << 1) * (N << 1); const int INF = 0x3f3f3f3f; int n, cnt, s, t, cost; int idx, head[N << 1], ver[M << 1], next[M << 1]; std::pair edge[M << 1]; std::unordered_map cnt_x, cnt_y, id_x, id_y; std::set> set; int dist[N << 1]; bool vis[N << 1]; void add(int u, int v, int flow, int cost) { next[idx] = head[u]; ver[idx] = v; edge[idx] = std::make_pair(flow, cost); head[u] = idx++; } bool spfa() { std::fill(std::begin(vis), std::end(vis), false); std::fill(std::begin(dist), std::end(dist), INF); std::queue q; q.emplace(s); dist[s] = 0; vis[s] = true; while (!q.empty()) { int u = q.front(); q.pop(); vis[u] = false; for (int i = head[u]; ~i; i = next[i]) { int v = ver[i], flow = edge[i].first, cost = edge[i].second; if (flow && dist[v] > dist[u] + cost) { dist[v] = dist[u] + cost; if (!vis[v]) { q.emplace(v); vis[v] = true; } } } } return dist[t] != INF; } int dinic(int u, int limit) { if (u == t) return limit; int flow = 0; vis[u] = true; for (int i = head[u]; ~i && flow < limit; i = next[i]) { int v = ver[i], f = edge[i].first, w = edge[i].second; if (dist[v] == dist[u] + w && f && !vis[v]) { int k = dinic(v, std::min(f, limit - flow)); if (!k) dist[v] = INF; edge[i].first -= k; edge[i ^ 1].first += k; flow += k; cost += k * w; } } vis[u] = false; return flow; } int main() { std::ios::sync_with_stdio(false); cin.tie(nullptr); std::fill(std::begin(head), std::end(head), -1); cin >> n; for (int i = 1, x, y; i <= n; i++) { cin >> x >> y; cnt_x[x]++, cnt_y[y]++; set.emplace(x, y); if (!id_x.count(x)) id_x[x] = ++cnt; if (!id_y.count(y)) id_y[y] = ++cnt; } s = 0, t = cnt + 1; for (auto o : id_x) { add(s, o.second, cnt_x[o.first], 0); add(o.second, s, 0, 0); } for (auto o : id_y) { add(o.second, t, cnt_y[o.first], 0); add(t, o.second, 0, 0); } for (auto a : id_x) { for (auto b : id_y) { if (set.count(std::make_pair(a.first, b.first))) { add(a.second, b.second, 1, 1); add(b.second, a.second, 0, -1); } else { add(a.second, b.second, 1, 0); add(b.second, a.second, 0, 0); } } } while (spfa()) dinic(s, INF); cout << cost << endl; return 0; }