#include <stdio.h>
#include <unordered_map>
#include <set>
#include <map>
#include <algorithm>

using namespace std;

int t[100000];
int a[100000];
int b[100000];
int y[100000];

bool ok[100000];

#define B 100

typedef struct
{
	int d[B];
	int n[B];
	bool l[B];
	int ad;
	int an;
	bool al;
	int m;
}point;

point d[200000 / B];

bool hazi(int o,int b,int e,int n)
{
	if(d[o].al)
	{
		if(d[o].an == y[n])
		{
			ok[n] = true;
		}
		else if(d[o].an < y[n])
		{
			return false;
		}
	}
	else
	{
		for(int i = b; i < e; i++)
		{
			if(d[o].l[i])
			{
				if(d[o].n[i] == y[n])
				{
					ok[n] = true;
				}
				else if(d[o].n[i] < y[n])
				{
					return false;
				}
			}
			else
			{
				if(d[o].d[i] < y[n])
				{
					d[o].d[i] = y[n];
				}
			}
		}
	}
	return true;
}

void hazi2(int o,int a,int e,int yw)
{
	if(d[o].al)
	{
		for(int i = 0; i < B; i++)
		{
			if(!d[o].l[i])
			{
				d[o].d[i] = max(d[o].d[i],d[o].ad);
			}
			d[o].n[i] = d[o].an;
			d[o].l[i] = true;
		}
		d[o].al = false;
	}
	for(int i = a; i < e; i++)
	{
		d[o].n[i] = yw;
		d[o].l[i] = true;
	}
	int minw = 1111111111;
	for(int i = 0; i < B; i++)
	{
		if(d[o].l[i])
		{
			minw = min(d[o].n[i],minw);
		}
	}
	d[o].m = minw;
}

bool naka(int o,int n)
{
	if(d[o].m == y[n])
	{
		ok[n] = true;
	}
	else if(d[o].m < y[n])
	{
		return false;
	}
	if(!d[o].al)
	{
		d[o].ad = max(d[o].ad,y[n]);
	}
	return true;
}

void naka2(int o,int yw)
{
	d[o].al = true;
	d[o].an = yw;
	d[o].m = yw;
}

void lastw(int o)
{
	for(int i = 0; i < B; i++)
	{
		if(!d[o].l[i])
		{
			d[o].d[i] = max(d[o].ad,d[o].d[i]);
		}
	}
}

pair<int,int> p[200000];

bool er[100000];

int main()
{
	int q;
	scanf("%d",&q);
	set<int> se;
	for(int i = 0; i < q; i++)
	{
		scanf("%d%d%d%d",t + i,a + i,b + i,y + i);
		se.insert(a[i]);
		se.insert(b[i] + 1);
		ok[i] = false;
	}
	unordered_map<int,int> mp;
	auto it = se.begin();
	int num = 0;
	for( ; it != se.end(); num++)
	{
		mp.insert({*it,num});
		it++;
	}
	for(int i = 0; i < 200000 / B; i++)
	{
		for(int ii = 0; ii < B; ii++)
		{
			d[i].d[ii] = 0;
			d[i].l[ii] = false;
		}
		d[i].ad = 0;
		d[i].al = false;
		d[i].m = 1111111111;
	}
	for(int i = 0; i < q; i++)
	{
		if(t[i] == 0)
		{
			int aw = mp[a[i]];
			int bw = mp[b[i] + 1];
			if(aw / B == bw / B)
			{
				if(!hazi(aw / B,aw % B,bw % B,i))
				{
					printf("NO\n");
					return 0;
				}
			}
			else
			{
				if(!hazi(aw / B,aw % B,B,i))
				{
					printf("NO\n");
					return 0;
				}
				for(int ii = aw / B + 1; ii < bw / B; ii++)
				{
					if(!naka(ii,i))
					{
						printf("NO\n");
						return 0;
					}
				}
				if(!hazi(bw / B,0,bw % B,i))
				{
					printf("NO\n");
					return 0;
				}
			}
		}
		else
		{
			int aw = mp[a[i]];
			int bw = mp[b[i] + 1];
			if(aw / B == bw / B)
			{
				hazi2(aw / B,aw % B,bw % B,y[i]);
			}
			else
			{
				hazi2(aw / B,aw % B,B,y[i]);
				for(int ii = aw / B + 1; ii < bw / B; ii++)
				{
					naka2(ii,y[i]);
				}
				hazi2(bw / B,0,bw % B,y[i]);
			}
		}
	}
	for(int i = 0; i < 200000 / B; i++)
	{
		lastw(i);
	}
	int nw = 0;
	for(int i = 0; i < q; i++)
	{
		if(t[i] == 0)
		{
			int aw = mp[a[i]];
			int bw = mp[b[i] + 1];
			p[nw] = make_pair(aw,i);
			nw++;
			p[nw] = make_pair(bw,-i - 1);
			nw++;
			er[i] = false;
		}
	}
	sort(p,p + nw);
	multimap<int,int> se2;
	int nowb = 0;
	for(int i = 0; i < num; i++)
	{
		while(nowb < nw && p[nowb].first <= i)
		{
			if(p[nowb].second < 0)
			{
				int b = -p[nowb].second - 1;
				if(!er[b])
				{
					auto itw = se2.find(y[b]);
					while((*itw).second != b)
					{
						itw++;
					}
					se2.erase(itw);
				}
			}
			else
			{
				int b = p[nowb].second;
				se2.insert({y[b],b});
			}
			nowb++;
		}
		auto itt = se2.find(d[i / B].d[i % B]);
		while(itt != se2.end() && (*itt).first == d[i / B].d[i % B])
		{
			ok[(*itt).second] = true;
			er[(*itt).second] = true;
			auto itw = itt;
			itt++;
			se2.erase(itw);
		}
	}
	for(int i = 0; i < q; i++)
	{
		if(t[i] == 0)
		{
			if(!ok[i])
			{
				printf("NO\n");
				return 0;
			}
		}
	}
	printf("YES\n");
}

Measured memory_bytes: 14256