#include #define REP(i, n) for(int i = 0 ; i< (int)n; ++i) using namespace std; struct V { int x; int y; bool visited; bool part; vector edges; vector matched; }; bool dfs(vector& path, vector& vs) { /* for(auto& x : path) cerr << x << " "; cerr << endl; */ int from = path[path.size()-1]; if(vs[from].visited) return false; vs[from].visited = true; bool found = false; for(int i = 0; i < vs[from].edges.size(); i++) { if(vs[from].matched[i] != vs[from].part) { found = true; path.push_back(vs[from].edges[i]); if(dfs(path, vs)) return true; path.pop_back(); } } if(!vs[from].part && !found) return true; return false; } bool testcase(){ int n; if(!(cin >> n))return false; vector vs; for(int i = 0; i < n; i++) { int x, y; cin >> x >> y; vs.push_back(V{x, y, false}); for(int j = 0; j < i; j++) { if(abs(vs[j].x - vs[i].x) + abs(vs[j].y - vs[i].y) == 1) { vs[i].edges.push_back(j); vs[j].edges.push_back(i); } } } vector left; vector right; stack s; s.push(0); vs[0].part = true; while(!s.empty()) { auto id = s.top(); s.pop(); if(vs[id].visited) continue; vs[id].visited = true; for(auto& n : vs[id].edges) { vs[n].part = !vs[id].part; s.push(n); } } /* for(auto& v : vs) { cerr << "(" << v.x << "," << v.y << ") " << v.part << " | "; for(auto& i : v.edges) cerr << "(" << vs[i].x << "," << vs[i].y << ") "; cerr << endl; } */ for(auto& v : vs) v.matched.resize(v.edges.size()); while(true) { for(auto& v : vs) v.visited = false; bool found = false; vector path; for(int i = 0; i < n && !found; i++) { bool isFree = true; for(auto m : vs[i].matched) if(m) isFree = false; if(!isFree) continue; if(vs[i].part) { path.push_back(i); if(dfs(path, vs)) { found = true; break; } path.pop_back(); } } if(!found) break; for(int i = 0; i < path.size() - 1; i++) { int u = path[i]; int v = path[i + 1]; for(int j = 0; j < vs[u].edges.size(); j++) if(vs[u].edges[j] == v) vs[u].matched[j] = !vs[u].matched[j]; for(int j = 0; j < vs[v].edges.size(); j++) if(vs[v].edges[j] == u) vs[v].matched[j] = !vs[v].matched[j]; } } // cerr << "matching:\n"; /* for(int i = 0; i < n; i++) for(int j = 0; j < vs[i].edges.size(); j++) if(vs[i].edges[j] < i) std::cerr << "(" << vs[i].x << "," << vs[i].y << ") (" << vs[vs[i].edges[j]].x << "," << vs[vs[i].edges[j]].y << ")" << vs[i].matched[j] << endl; */ int result = n; for(int i = 0; i < n; i++) for(int j = 0; j < vs[i].edges.size(); j++) if(vs[i].edges[j] < i && vs[i].matched[j]) result--; cout << result << endl; return true; } int main(){ while(testcase()); return 0; }