#include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

const int INF = int(1.05e9);

inline unsigned int getHighestOneBit(unsigned int x) {
	/*
	x |= (x >> 1);
	x |= (x >> 2);
	x |= (x >> 4);
	x |= (x >> 8);
	x |= (x >> 16);
	return x & ~(x >> 1);
	*/
	return 1<<(31 - __builtin_clz(x));
}

class SegMax {
	int N;
	vector<int> maxi;
	inline void doit(int k, int x) {maxi[k] = max(maxi[k], x);}
public:
	SegMax(int n) : N(n == 1 ? 1 : 1<<(32 - __builtin_clz(n - 1))), maxi(2*N, 0) {}
	int query(int k) {
		int ans = 0;
		for (k+=N;k>0;k>>=1) ans = max(ans, maxi[k]);
		return ans;
	}

	void fill(int s, int t, int x) {
		for (int idx;0<s && s+(s&-s)<=t && (idx=(N+s)/(s&-s)); s+=s&-s) doit(idx, x);
		for (int idx;s<t && (idx=(N+t)/(t&-t)-1); t-=t&-t) doit(idx, x);
	}
};

class SegRMQ {
	int N;
	vector<pair<int, bool> > datas;//(mini, uniform)
	inline void update(int k) {
		datas[k].first = min(datas[2*k].first, datas[2*k+1].first);
	}
	inline void prop(int k) {
		if (datas[k].second) {
			datas[2*k] = datas[2*k+1] = datas[k];
			datas[k].second = false;
		}
	}
	inline int getWidth(int i) {
		return N / getHighestOneBit(i);
	}
public:
	SegRMQ(const vector<int>& ns) {
		N = ns.size() == 1 ? 1 : 1<<(32 - __builtin_clz(int(ns.size())-1));
		datas.assign(2*N, make_pair(INF, false));
		for (int i = 0; i < int(ns.size()); ++i) {
			datas[i+N].first = ns[i];
		}
		for (int i = N - 1 ; i > 0; --i) update(i);
	}

	int getMin(int L, int R) {
		int hw = N/2, k = 1, l = 0, ans = INF;
		for(;k<N && R-L!=2*hw;k=2*k+(R>l+hw),l+=(R>l+hw?hw:0),hw>>=1){
			prop(k);
			if(R > l + hw && l + hw > L) break;
		}
		if(R-L==2*hw || k>=N){
			return datas[k].first;
		}

		for(int lk=k*2,lw=getWidth(lk),ll=lk*lw-N;;){
			if(ll==L){
				ans = min(ans, datas[lk].first);
				break;
			}
			prop(lk);
			lk = 2*lk + 1;
			lw >>= 1;
			if(L<ll+lw){
				ans = min(ans, datas[lk].first);
				lk ^= 1;
			}
			else{
				ll += lw;
			}
		}

		for(int rk=2*k+1,rw=getWidth(rk),rl=rk*rw-N;;){
			if(rl+rw==R){
				ans = min(ans, datas[rk].first);
				break;
			}
			prop(rk);
			rk = 2*rk;
			rw >>= 1;
			if(rl+rw<R){
				ans = min(ans,datas[rk].first);
				rk ^= 1;
				rl += rw;
			}
		}

		return ans;
	}

	void fill(int L, int R, int x) {
		int hw = N/2, k = 1, l = 0;
		for(;k<N && R-L!=2*hw;k=2*k+(R>l+hw),l+=(R>l+hw?hw:0),hw>>=1){
			prop(k);
			if(R > l + hw && l + hw > L) break;
		}
		if(R-L==2*hw || k>=N){
			datas[k] = make_pair(x,true);
			for(;k>>=1;) update(k);
			return ;
		}

		for(int lk=k*2,lw=getWidth(lk),ll=lk*lw-N;;){
			if(ll==L){
				datas[lk] = make_pair(x,true);
				for (;(lk>>=1)>k;) update(lk);
				break;
			}
			prop(lk);
			lk = 2*lk + 1;
			lw >>= 1;
			if(L<ll+lw){
				datas[lk] = make_pair(x,true);
				lk ^= 1;
			}
			else{
				ll += lw;
			}
		}

		for(int rk=2*k+1,rw=getWidth(rk),rl=rk*rw-N;;){
			if(rl+rw==R){
				datas[rk] = make_pair(x,true);
				for (;rk>>=1;) update(rk);
				break;
			}
			prop(rk);
			rk = 2*rk;
			rw >>= 1;
			if(rl+rw<R){
				datas[rk] = make_pair(x,true);
				rk ^= 1;
				rl += rw;
			}
		}
	}
};

const int MAX_N = int(5e4);
int as[MAX_N], bs[MAX_N], ys[MAX_N], ns[2*MAX_N], ts[MAX_N];

int main() {
	int n; scanf("%d", &n);
	int L = 0;
	for (int i = 0; i < n; ++i) {
		scanf("%d%d%d%d", ts+i, as+i, bs+i, ys+i);
		++bs[i];
		ns[L++] = as[i];
		ns[L++] = bs[i];
	}
	sort(ns, ns + L);
	L = unique(ns, ns+L) - ns;
	for (int i = 0; i < n; ++i) {
		as[i] = lower_bound(ns, ns+L, as[i]) - ns;
		bs[i] = lower_bound(ns, ns+L, bs[i]) - ns;
	}

	SegMax seg(L);
	set<int> ids;
	vector<int> xs(L);
	for (int i = 0; i < L; ++i) {
		ids.insert(i);
	}
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0) {
			seg.fill(as[i], bs[i], ys[i]);
		}
		else {
			for (set<int>::iterator itr = ids.lower_bound(as[i]); itr != ids.end() && *itr < bs[i]; ids.erase(itr++)) {
				xs[*itr] = seg.query(*itr);
			}
		}
	}
	for (set<int>::iterator itr = ids.begin(); itr != ids.end(); ++itr) {
		xs[*itr] = seg.query(*itr);
	}
	SegRMQ rmq(xs);
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0 && rmq.getMin(as[i], bs[i]) != ys[i]) {
			puts("NO");
			return 0;
		}
		else if (ts[i] == 1) {
			rmq.fill(as[i], bs[i], ys[i]);
		}
	}
	puts("YES");

	return 0;
}

Measured memory_bytes: 8124