import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)


class UF_tree:
    def __init__(self, n):
        self.root = [-1] * (n + 1)
        self.rank = [0] * (n + 1)

    def find(self, x):
        if self.root[x] < 0:
            return x
        self.root[x] = self.find(self.root[x])
        return self.root[x]

    def isSame(self, x, y):
        return self.find(x) == self.find(y)

    def unite(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return False
        if self.rank[x] < self.rank[y]:
            self.root[y] += self.root[x]
            self.root[x] = y
        else:
            self.root[x] += self.root[y]
            self.root[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1
        return True

    def size(self, x):
        return -self.root[self.find(x)]


N = int(input())
U = 101 * 101
uf = UF_tree(U)
G = [[] for _ in range(U)]
for _ in range(N):
    x, y, xx, yy = map(int, input().split())
    s = x * 101 + y
    t = xx * 101 + yy
    uf.unite(s, t)
    G[s].append(t)
    G[t].append(s)

leader = {uf.find(i) for i in range(U)}
group = {i: [] for i in leader}
for i in range(U):
    group[uf.find(i)].append(i)

ok = True
for g in group.values():
    edge = 0
    for i in g:
        edge += len(G[i])
    edge //= 2
    if edge > len(g):
        ok = False

if ok:
    print("YES")
else:
    print("NO")