#include using namespace std; #define rep(i, a, b) for (int i= a; i < (b); ++i) #define all(x) begin(x), end(x) #define sz(x) (x).size() #define int ll #define F first #define S second #define PB push_back #define MP make_pair typedef long long int; typedef pair pii; typedef vector vi; #define endl '\n' #define inf 3000000000000000000 #define random rand()^(rand()<<15) mt19937 rnd(time(nullptr)); namespace std { template<> struct hash { size_t operator()(pii const& s) const noexcept { return ((size_t)s.F) + ((size_t)s.S) * 970592641; } }; } unordered_map> nodes; unordered_map groups; bool mark_groups(pii node, pii parent, ll id) { if (groups.find(node) != groups.end()) return true; groups[node] = id; for (pii nei : nodes[node]) { if (nei == parent) continue; if (mark_groups(nei, node, id)) return true; } return false; } array deltas = {{ {0, 1}, {1, 0}, {0, -1}, {-1, 0} }}; ll solve() { ll next_id = 0; for (auto pair : nodes) { pii node = pair.F; if (groups.find(node) != groups.end()) continue; if (mark_groups(node, node, next_id++)) return 0; } std::vector conn; for (auto pair : nodes) { pii a = pair.F; for (pii delta : deltas) { pii b = {a.F + delta.F, a.S + delta.S}; if (nodes.find(b) == nodes.end()) continue; bool found = false; for (pii nei : nodes[a]) { if (nei == b) found = true; } if (found) continue; ll ga = groups[a]; ll gb = groups[b]; if (ga > gb) swap(ga, gb); if (ga == gb) return 1; conn.push_back({ga, gb}); } } unordered_set found; for (pii c : conn) { if (found.find(c) != found.end()) return 2; found.insert(c); } return 3; } signed main() { cin.tie(0)->sync_with_stdio(0); ll edge_count; cin >> edge_count; for (ll i = 0; i < edge_count; i++) { pii a; pii b; cin >> a.F >> a.S >> b.F >> b.S; nodes[a].push_back(b); nodes[b].push_back(a); } cout << solve() << endl; return 0; }