from collections import defaultdict

def claim(n):
    global answer
    answer = min(answer, n)

def any_in(where, *items):
    for item in items:
        if item in where: return True
    return False

answer = 3

n = int(input())

neighbours = defaultdict(list)
nodes = set()
edges = set()

for _ in range(n):
    x1, y1, x2, y2 = map(int, input().split())
    nodes.add((x1, y1))
    nodes.add((x2, y2))
    neighbours[x1, y1].append((x2, y2))
    neighbours[x2, y2].append((x1, y1))
    edges.add((x1, y1, x2, y2))
    edges.add((x2, y2, x1, y1))

    if x1 == x2:
        if any_in(edges,
                  (x1, y1, x1 - 1, y1), (x1, y1, x1 + 1, y1),
                  (x1, y2, x1 - 1, y2), (x1, y2, x1 + 1, y2),
                  (x1 - 1, y1, x1 - 1, y2), (x1 + 1, y1, x1 + 1, y2),
        ):
            claim(2)
        
    if y1 == y2:
        if any_in(edges,
                  (y1, x1, y1 - 1, x1), (y1, x1, y1 + 1, x1),
                  (y1, x2, y1 - 1, x2), (y1, x2, y1 + 1, x2),
                  (y1 - 1, x1, y1 - 1, x2), (y1 + 1, x1, y1 + 1, x2),
        ):
            claim(2)
    
global_seen = set()
for start_node in nodes:
    if nodes in global_seen: continue
    seen = set()
    stack = [(start_node, (None, None))]
    while stack:
        (x, y), (px, py) = stack.pop()
        if (x, y) in seen:
            claim(0)
            continue
        seen.add((x, y))
        for dx, dy in [(-1, 0), (0, -1), (0, 1), (1, 0)]:
            nx, ny = x + dx, y + dy
            if (nx, ny) == (px, py): continue
            claim(1)
        for nx, ny in neighbours[x, y]:
            if (nx, ny) == (px, py): continue
            stack.append(((nx, ny), (x, y)))

print(answer)
