#include "bits/stdc++.h"
using namespace std;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i))
#define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i))
static const int INF = 0x3f3f3f3f; static const long long INFL = 0x3f3f3f3f3f3f3f3fLL;
typedef vector<int> vi; typedef pair<int, int> pii; typedef vector<pair<int, int> > vpii; typedef long long ll;
template<typename T, typename U> static void amin(T &x, U y) { if (y < x) x = y; }
template<typename T, typename U> static void amax(T &x, U y) { if (x < y) x = y; }

struct UnionFind {
	vector<int> data;
	void init(int n) { data.assign(n, -1); }
	bool unionSet(int x, int y) {
		x = root(x); y = root(y);
		if (x != y) {
			if (data[y] < data[x]) swap(x, y);
			data[x] += data[y]; data[y] = x;
		}
		return x != y;
	}
	bool findSet(int x, int y) { return root(x) == root(y); }
	int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
	int size(int x) { return -data[root(x)]; }
};

int main() {
	int N;
	while (~scanf("%d", &N)) {
		UnionFind uf;
		uf.init(101 * 101);
		vector<int> count(101 * 101);
		rep(i, N) {
			int y1; int x1; int y2; int x2;
			scanf("%d%d%d%d", &y1, &x1, &y2, &x2), -- y1, -- x1, -- y2, -- x2;
			int a = y1 * 101 + x1, b = y2 * 101 + x2;
			++ count[a];
			uf.unionSet(a, b);
		}
		vi num2(count.size()), num=num2;
		rep(i, count.size()) {
			++ num2[uf.root(i)];
			num[uf.root(i)] += count[i];
		}
		bool ans = true;
		rep(i, count.size())
			ans &= num[i]<=num2[i];
		puts(ans ? "YES" : "NO");
	}
	return 0;
}