from collections import defaultdict

def claim(n):
    global answer
    if n < answer: answer = n

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

def claim_square(x, y):
    square_counts[x, y] += 1
    return square_counts[x, y] > 1

answer = 3

n = int(input())

neighbours = defaultdict(list)
nodes = set()
#edges = set()
square_counts = defaultdict(int)

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,
                  (x1, y1, x1, y1 - 1), (x1, y1, x1, y1 + 1),
                  (x2, y1, x2, y1 - 1), (x2, y1, x2, y1 + 1),
                  (x1, y1 - 1, x2, y1 - 1), (x1, y1 + 1, x2, y1 + 1),
        ):
            claim(2)'''
    
    if answer <= 2: continue

    if x1 == x2:
        if y2 < y1: y1, y2 = y2, y1
        if claim_square(x1 - 1, y1) or claim_square(x1, y1):
            claim(2)
    
    if y1 == y2:
        if x2 < x1: x1, x2 = x2, x1
        if claim_square(x1, y1 - 1) or claim_square(x1, y1):
            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)
            break
        seen.add((x, y))
        if answer > 1:
            for dx, dy in [(-1, 0), (0, -1), (0, 1), (1, 0)]:
                nx, ny = x + dx, y + dy
                if (nx, ny) == (px, py): continue
                if (nx, ny) in seen: claim(1)
        for nx, ny in neighbours[x, y]:
            if (nx, ny) == (px, py): continue
            stack.append(((nx, ny), (x, y)))
    if answer == 0: break
    global_seen |= seen

print(answer)
