In this problem at each moment you have a set of intervals. You can move from interval (a, b) from our set to interval (c, d) from our set if and only if c < a < d or c < b < d. Also there is a path from interval I_1 from our set to interval I_2 from our set if there is a sequence of successive moves starting from I_1 so that we can reach I_2.

Your program should handle the queries of the following two types:  "1 x y" (x < y) — add the new interval (x, y) to the set of intervals. The length of the new interval is guaranteed to be strictly greater than all the previous intervals. "2 a b" (a ≠ b) — answer the question: is there a path from a-th (one-based) added interval to b-th (one-based) added interval? 

Answer all the queries. Note, that initially you have an empty set of intervals.


-----Input-----

The first line of the input contains integer n denoting the number of queries, (1 ≤ n ≤ 100). Each of the following lines contains a query as described above. All numbers in the input are integers and don't exceed 10^9 by their absolute value.

It's guaranteed that all queries are correct.


-----Output-----

For each query of the second type print "YES" or "NO" on a separate line depending on the answer.


-----Examples-----
Input
5
1 1 5
1 5 11
2 1 2
1 2 9
2 1 2

Output
NO
YES

Difficulty: MEDIUM
Tags: Graph algorithms

Graph traversal

Starter code:

Solutions:
import math

class Pair:

	def __init__(self, x=0, y=0):
		self.x = x
		self.y = y
		self.neighbors = []
		self.visited = False

def isMedian(pair1, pair2):
	if pair1.x > pair2.x and pair1.x < pair2.y:
		return True
	elif pair1.y > pair2.x and pair1.y < pair2.y:
		return True
	else:
		return False

def dfs(startPair, targPair):
	stack = []
	stack.append(startPair)
	while len(stack) > 0:
		currPair = stack.pop()
		if currPair.visited == True:
			continue
		currPair.visited = True
		if currPair.x == targPair.x and currPair.y == targPair.y:
			return True
		for n in currPair.neighbors:
			stack.append(n)
	return False
numQueries = input()
numQueries = int(numQueries)
count = 0
pairs = {}
results = []
for x in range(0, numQueries):
	nums = list(map(int, input().split()))
	queryType = nums[0]
	first = nums[1]
	second = nums[2]
	if queryType == 1:
		newPair = Pair(first, second)
		for key in pairs:
			if isMedian(newPair, pairs[key]) == True:
				newPair.neighbors.append(pairs[key])
			if isMedian(pairs[key], newPair) == True:
				pairs[key].neighbors.append(newPair)
		pairs[count] = newPair
		count += 1
	else:
		firstPair = pairs[first - 1]
		secondPair = pairs[second - 1]
		for tempKey in pairs:
			pairs[tempKey].visited = False
		if dfs(firstPair, secondPair) == True:
			results.append('YES')
		else:
			results.append('NO')
for result in results:
	print(result)


(_set, h) = ([], [])

def dfs(a, b, Len, h):
	if a == b:
		return True
	Len[a] = True
	for x in h[a]:
		if not Len[x] and dfs(x, b, Len, h):
			return True
	return False
for i in range(int(input())):
	(q, x, y) = map(int, input().split())
	if q == 1:
		_set.append((x, y))
		h.append([])
		for (i, part_set) in enumerate(_set):
			if x in range(part_set[0] + 1, part_set[1]) or y in range(part_set[0] + 1, part_set[1]):
				h[-1].append(i)
			if part_set[0] in range(x + 1, y) or part_set[1] in range(x + 1, y):
				h[i].append(len(_set) - 1)
	else:
		print('YES' if dfs(x - 1, y - 1, [False] * len(_set), h) else 'NO')


def recursive_dfs(graph, start, path=[]):
	path = path + [start]
	for node in graph[start]:
		if not node in path:
			path = recursive_dfs(graph, node, path)
	return path

def conn(x, y):
	(a, b) = (x[0], x[1])
	(c, d) = (y[0], y[1])
	return c < a < d or c < b < d
adj = {}
vert = []
n = int(input())
for i in range(n):
	(a, b, c) = list(map(int, input().split(' ')))
	if a == 1:
		incoming = (b, c)
		adj[incoming] = []
		for vertex in vert:
			if conn(vertex, incoming):
				adj[vertex].append(incoming)
			if conn(incoming, vertex):
				adj[incoming].append(vertex)
		vert.append(incoming)
	if a == 2:
		check = vert[b - 1]
		in_chk = vert[c - 1]
		if in_chk in recursive_dfs(adj, check):
			print('YES')
		else:
			print('NO')


def DFS(v, b, visited):
	visited.add(v)
	global count, matrix, ok
	if v == b:
		ok = True
		return
	for i in range(count):
		if matrix[v][i] == 1 and v != i and (i not in visited):
			DFS(i, b, visited)
n = int(input())
matrix = [[0] * 111 for i in range(111)]
count = 0
ok = False
intervals = []
for i in range(n):
	(t, a, b) = map(int, input().split())
	if t == 1:
		intervals.append((a, b))
		for l in range(count):
			(c, d) = intervals[l]
			if c < a < d or c < b < d:
				matrix[count][l] = 1
			if a < c < b or a < d < b:
				matrix[l][count] = 1
		count += 1
	if t == 2:
		visited = set()
		ok = False
		res = DFS(a - 1, b - 1, visited)
		if ok:
			print('YES')
		else:
			print('NO')


import collections
_n = input()
n = int(_n)
int_list = list()
first = (0, 0)
int_list.append(first)
graph = {}
for x in range(n):
	q = input().split()
	a = int(q[1])
	b = int(q[2])
	interval = (a, b)
	if q[0] == '1':
		int_list.append(interval)
		val = list()
		for k in graph.keys():
			it = graph[k]
			c = k[0]
			d = k[1]
			if a > c and a < d:
				val.append((c, d))
			elif b > c and b < d:
				val.append((c, d))
			if c > a and c < b:
				it.append(interval)
			elif d > a and d < b:
				it.append(interval)
			graph[k] = it
		graph[interval] = val
	elif q[0] == '2':
		beg = a
		end = b
		beg_int = int_list[beg]
		end_int = int_list[end]
		visited = set()
		que = collections.deque()
		que.append(beg_int)
		found = False
		while que:
			i = que.pop()
			adj_list = graph[i]
			if i[0] == end_int[0] and i[1] == end_int[1]:
				found = True
				break
			visited.add(i)
			for a_int in adj_list:
				if a_int not in visited:
					que.append(a_int)
		if found:
			print('YES')
		else:
			print('NO')


def is_conn(i1, i2):
	(a, b) = i1
	(c, d) = i2
	return c < a < d or c < b < d
neighbors = {}
intervals = []
n = int(input())
for i in range(0, n):
	(q, x, y) = [int(j) for j in input().split()]
	if q == 1:
		ourint = (x, y)
		intervals.append(ourint)
		neighbors[ourint] = []
		for interval in intervals:
			if is_conn(interval, ourint):
				neighbors[interval].append(ourint)
			if is_conn(ourint, interval):
				neighbors[ourint].append(interval)
	if q == 2:
		x -= 1
		y -= 1
		a = intervals[x]
		b = intervals[y]
		visited = {a}
		query = [a]
		while len(query) > 0:
			j = query[0]
			query = query[1:]
			for nei in neighbors[j]:
				if not nei in visited:
					query.append(nei)
					visited = visited | {nei}
		if b in visited:
			print('YES')
		else:
			print('NO')


from collections import deque

def filter_intervals(intv, input_list):
	return ((x, y) for (x, y) in input_list if int(intv[0]) > int(x) and int(intv[0]) < int(y) or (int(intv[1]) > int(x) and int(intv[1]) < int(y)))

def interval_search(intv, target, input_list):
	visited = set()
	d = deque()
	d.append(intv)
	while d:
		intv = d.pop()
		if intv == target:
			return True
		if intv not in visited:
			visited.add(intv)
			for interval in filter_intervals(intv, input_list):
				if interval not in visited:
					d.append(interval)
	return False

def main():
	num_inputs = int(input())
	interval_list = []
	for _ in range(num_inputs):
		(input_type, beg, end) = input().split()
		beg = int(beg)
		end = int(end)
		if int(input_type) == 1:
			interval_list.append((beg, end))
		elif interval_search(interval_list[beg - 1], interval_list[end - 1], interval_list):
			print('YES')
		else:
			print('NO')

def __starting_point():
	main()
__starting_point()


import sys
f = sys.stdin
intervals = []

def check_intervals(a, b):
	return b[0] < a[0] and a[0] < b[1] or (b[0] < a[1] and a[1] < b[1])

def find_path(a, b):
	visited = [False] * len(intervals)
	stack = [a]
	while len(stack) != 0:
		i = stack.pop()
		if i == b:
			return True
		if visited[i] == True:
			continue
		visited[i] = True
		options = []
		for x in range(len(intervals)):
			if not visited[x] and check_intervals(intervals[i], intervals[x]):
				stack.append(x)
	return False
num_queries = int(f.readline().strip())
for i in range(num_queries):
	(a, b, c) = [int(x) for x in f.readline().strip().split(' ')]
	if a == 1:
		intervals.append((b, c))
	else:
		ans = 'YES' if find_path(b - 1, c - 1) else 'NO'
		print(ans)


def get_operations():
	n = int(input())
	return [tuple((int(k) for k in input().split())) for _ in range(n)]

def can_move(a, b):
	(x1, y1) = a
	(x2, y2) = b
	return x2 < x1 and x1 < y2 or (x2 < y1 and y1 < y2)

def can_reach(intervals, x, y, mask=[]):
	if not mask:
		mask = [False] * len(intervals)
	if x == y:
		return True
	mask[x] = True
	xs = [k for k in range(len(intervals)) if not mask[k] and can_move(intervals[x], intervals[k])]
	return any((can_reach(intervals, k, y, mask) for k in xs))

def solve(operations):
	intervals = []
	results = []
	for op in operations:
		(t, x, y) = op
		if t == 1:
			intervals.append(tuple([x, y]))
		else:
			results.append(can_reach(intervals, x - 1, y - 1))
	return results
operations = get_operations()
results = solve(operations)
for res in results:
	print('YES' if res else 'NO')


visited = [0 for i in range(110)]

def reset():
	nonlocal N, visited
	for i in range(N):
		visited[i] = 0

def dfs(s, e):
	nonlocal N, nodes, visited
	if s == e:
		return True
	if visited[s] == 1:
		return False
	visited[s] = 1
	ans = False
	for i in range(N):
		if i == s:
			continue
		a = nodes[s][0]
		b = nodes[s][1]
		c = nodes[i][0]
		d = nodes[i][1]
		if c < a and a < d or (c < b and b < d):
			ans = ans or dfs(i, e)
	return ans
nodes = []
N = 0
M = int(input())
for k in range(M):
	(con, u, v) = tuple((int(i) for i in input().split()))
	if con == 1:
		V = [u, v]
		nodes.append(V)
		N += 1
	else:
		u -= 1
		v -= 1
		reset()
		if dfs(u, v):
			print('YES')
		else:
			print('NO')


n = int(input())

class Graph:

	def __init__(self, V):
		self.V = V
		self.adj = [[] for i in range(V)]

	def DFSUtil(self, temp, v, y, visited):
		visited[v] = True
		if v == y:
			return True
		for i in self.adj[v]:
			if visited[i] == False:
				temp = self.DFSUtil(temp, i, y, visited)
				if temp == True:
					return True
		return False

	def addEdge(self, v, w):
		self.adj[v].append(w)

	def connectedComponents(self):
		visited = []
		cc = []
		for i in range(self.V):
			visited.append(False)
		for v in range(self.V):
			if visited[v] == False:
				temp = []
				cc.append(self.DFSUtil(temp, v, visited))
		return cc
node_values = [[0, 0]]
G = Graph(1)
cpunter = 1
for i in range(0, n):
	(q, a, b) = list(map(lambda x: int(x), input().split()))
	if q == 1:
		G.adj.append([])
		for k in range(1, len(node_values)):
			if a < node_values[k][0] < b or a < node_values[k][1] < b:
				G.addEdge(k, G.V)
			if node_values[k][0] < a < node_values[k][1] or node_values[k][0] < b < node_values[k][1]:
				G.addEdge(G.V, k)
		node_values.append((a, b))
		G.V += 1
	else:
		visited = [False for _ in range(n)]
		if G.DFSUtil(False, a, b, visited):
			print('YES')
		else:
			print('NO')


from operator import xor

def dfs(d, start, finish):
	visited = []
	temp = []
	while True:
		if start not in visited:
			visited.append(start)
			[temp.append(item) for item in d[start]]
		if not temp:
			return False
		temp.reverse()
		start = temp.pop()
		temp.reverse()
		if start == finish:
			return True
n = int(input())
dict = {}
list = []
for i in range(n):
	line = [int(item) for item in input().split()]
	if line[0] == 1:
		dict[line[1], line[2]] = set()
		list.append((line[1], line[2]))
		for (a, b) in dict:
			if xor(line[1] < a and a < line[2], line[1] < b and b < line[2]):
				dict[line[1], line[2]].add((a, b))
				dict[a, b].add((line[1], line[2]))
			if a > line[1] and b < line[2]:
				dict[a, b].add((line[1], line[2]))
	else:
		first = list[line[1] - 1]
		finish = list[line[2] - 1]
		if dfs(dict, first, finish):
			print('YES')
		else:
			print('NO')


from collections import defaultdict
get_input = lambda : list(map(int, input().split()))
zero = lambda : 0
adj_list = defaultdict(set)
edges = {}

def hasPath(a, b, c, d):
	return c < a < d or c < b < d

def update_edge(index, a, b):
	global edges
	edges[index] = (a, b)
	for (i, e) in edges.items():
		start = e[0]
		end = e[1]
		if hasPath(start, end, a, b):
			adj_list[i].add(index)
		if hasPath(a, b, start, end):
			adj_list[index].add(i)

def dfs(start, end):
	toVisit = [start]
	visited = defaultdict(zero)
	while not len(toVisit) == 0:
		c = toVisit.pop()
		if visited[c] == 0:
			visited[c] = 1
			if c == end:
				return True
			for v in adj_list[c]:
				if visited[v] == 0:
					toVisit.append(v)
	return False
count = 1
num_queries = int(input())
for i in range(num_queries):
	query = get_input()
	(type, start, end) = (query[0], query[1], query[2])
	if type == 1:
		update_edge(count, start, end)
		count += 1
	else:
		print('YES') if dfs(query[1], query[2]) else print('NO')


import collections

def do():
	n = int(input())
	intervals = [[-1, -1]]
	res = []

	def bfs(i):
		q = collections.deque()
		seen[i] = 1
		q.append(i)
		while q:
			cur = q.popleft()
			for j in range(1, len(intervals)):
				if not seen[j] and (intervals[j][0] < intervals[cur][0] < intervals[j][1] or intervals[j][0] < intervals[cur][1] < intervals[j][1]):
					seen[j] = 1
					q.append(j)
	for _ in range(n):
		nums = [int(c) for c in input().split(' ')]
		if nums[0] == 1:
			intervals.append(nums[1:])
		else:
			seen = [0] * (n + 1)
			bfs(nums[1])
			if seen[nums[2]]:
				res.append('YES')
			else:
				res.append('NO')
	for _ in res:
		print(_)
do()


from collections import deque

def solve():
	t = int(input().rstrip())
	nodes = []
	graph = {}
	for _ in range(t):
		(k, x, y) = list(map(int, input().rstrip().split()))
		if k == 1:
			nodes.append((x, y))
			if (x, y) not in graph:
				graph[x, y] = []
			for (a, b) in graph:
				if a < x < b or a < y < b:
					graph[x, y].append((a, b))
				if x < a < y or x < b < y:
					graph[a, b].append((x, y))
		elif k == 2:
			(a, b) = nodes[x - 1]
			(c, d) = nodes[y - 1]
			stack = deque()
			stack.append((a, b))
			seen = set()
			while len(stack) > 0 and (c, d) not in seen:
				(cur, dest) = stack.pop()
				seen.add((cur, dest))
				for (m, n) in graph[cur, dest]:
					if (m, n) not in seen:
						stack.append((m, n))
			if (c, d) in seen:
				print('YES')
			else:
				print('NO')

def __starting_point():
	solve()
__starting_point()


import sys
from collections import defaultdict
n = int(sys.stdin.readline().split()[0])
V = []
sett = defaultdict(set)
visited_sections = set()

def dfs(a, b):
	if a == b:
		return True
	for vis in sett[a]:
		if vis not in visited_sections:
			visited_sections.add(vis)
			if dfs(vis, b):
				return True
	return False
for i in range(n):
	(z, x, y) = (int(i) for i in sys.stdin.readline().split())
	if z == 1:
		for (a, b) in V:
			if a < x < b or a < y < b:
				sett[x, y].add((a, b))
			if x < a < y or x < b < y:
				sett[a, b].add((x, y))
		V.append((x, y))
	else:
		visited_sections.clear()
		if dfs(V[x - 1], V[y - 1]):
			print('YES')
		else:
			print('NO')


n = int(input())
arr = [0] * 102
arr2 = [0] * 102
visited = [0] * 102
var = 0

def fun(index):
	if var == visited[index]:
		return
	visited[index] = var
	for i in range(1, n + 1):
		if arr[i] < arr[index] < arr2[i]:
			fun(i)
		if arr[i] < arr2[index] < arr2[i]:
			fun(i)
count = 0
for x in range(n):
	(temp, x, y) = [int(i) for i in input().split()]
	if temp == 1:
		count += 1
		arr[count] = x
		arr2[count] = y
	else:
		var += 1
		fun(x)
		if visited[y] == var:
			print('YES')
		else:
			print('NO')


N = int(input())
points = []
visited = set()

def dfs(s, e):
	if s == e:
		return True
	for point in points:
		if (s[0] > point[0] and s[0] < point[1] or (s[1] > point[0] and s[1] < point[1])) and point not in visited:
			visited.add(point)
			if dfs(point, e):
				return True
	return False
for _ in range(N):
	(command, a, b) = [int(x) for x in input().rstrip().split(' ')]
	if command == 1:
		points.append((a, b))
	else:
		a -= 1
		b -= 1
		if a > len(points) - 1 or b > len(points) - 1:
			print('NO')
			continue
		visited.clear()
		visited.add(points[a])
		if dfs(points[a], points[b]):
			print('YES')
		else:
			print('NO')


from sys import stdin
input = stdin.readline
n = int(input())
r = [(0, 0)]
for _ in range(n):
	(q, x, y) = [int(x) for x in input().split()]
	if q == 1:
		r.append((x, y))
	else:
		stack = []
		stack.append(x)
		visited = [False] * len(r)
		visited[x] = True
		found = False
		while stack:
			node = stack.pop()
			if node == y:
				found = True
				break
			for i in range(1, len(r)):
				if not visited[i]:
					if r[i][0] < r[node][0] < r[i][1] or r[i][0] < r[node][1] < r[i][1]:
						visited[i] = True
						stack.append(i)
		if found:
			print('YES')
		else:
			print('NO')


n = int(input())
c = []
ind = 1
for i in range(n):
	(x, a, b) = map(int, input().split())
	if x == 1:
		c.append([a, b])
	else:
		u = [False] * len(c)
		g = [0] * len(c)
		l = 0
		r = 1
		g[l] = a - 1
		u[a - 1] = True
		while l < r:
			h = g[l]
			l += 1
			(x, y) = c[h]
			for j in range(len(c)):
				if (c[j][0] < x and x < c[j][1] or (c[j][0] < y and y < c[j][1])) and u[j] == False:
					g[r] = j
					u[j] = True
					r += 1
		if u[b - 1]:
			print('YES')
		else:
			print('NO')


from sys import stdin, stdout

def solve():
	n = int(stdin.readline().strip())
	li = []
	for _ in range(n):
		cmd = list(map(int, stdin.readline().split()))
		if cmd[0] == 1:
			li.append(cmd[1:])
		else:
			q = [cmd[1] - 1]
			vis = [False] * n
			vis[cmd[1] - 1] = True
			while len(q) > 0 and (not vis[cmd[2] - 1]):
				t = q.pop(0)
				for (i, e) in enumerate(li):
					if not vis[i] and (e[0] < li[t][0] < e[1] or e[0] < li[t][1] < e[1]):
						vis[i] = True
						if i == cmd[2] - 1:
							break
						q.append(i)
			print('YES' if vis[cmd[2] - 1] else 'NO')
	pass
LOCAL_TEST = not __debug__
if LOCAL_TEST:
	infile = __file__.split('.')[0] + '-test.in'
	stdin = open(infile, 'r')
tcs = int(stdin.readline().strip()) if LOCAL_TEST else 1
t = 1
while t <= tcs:
	solve()
	t += 1


from collections import defaultdict, namedtuple
Interv = namedtuple('Interv', ['a', 'b'])
g = defaultdict(set)
ordered = [None]

def path(i1, i2):
	(a, b, c, d) = (i1.a, i1.b, i2.a, i2.b)
	return c < a < d or c < b < d

def add(new_inter):
	ordered.append(new_inter)
	g[new_inter] = {other_inter for other_inter in g if path(new_inter, other_inter)}
	for other_inter in g:
		if path(other_inter, new_inter):
			g[other_inter].add(new_inter)
for _ in range(int(input())):
	(t, a, b) = map(int, input().split())
	if t == 1:
		add(Interv(a, b))
	else:
		(start, target) = (ordered[a], ordered[b])
		could = False
		visited = set()
		stack = [start]
		while stack:
			cur = stack.pop()
			if cur in visited:
				continue
			visited.add(cur)
			if cur == target:
				could = True
				break
			for nxt in g[cur]:
				stack.append(nxt)
		print('YES' if could else 'NO')


from collections import defaultdict, deque
n = int(input())
intervals = [(0, 0)]

def check_path(i1, i2):
	return i2[0] < i1[0] and i1[0] < i2[1] or (i2[0] < i1[1] and i1[1] < i2[1])
adj = defaultdict(list)

def bfs(n, t):
	q = deque()
	q.append(n)
	visited = set()
	while q:
		u = q.popleft()
		if u == t:
			return True
		visited.add(u)
		for v in adj[u]:
			if v not in visited:
				q.append(v)
	return False
for _ in range(n):
	(a, b, c) = map(int, input().split())
	if a == 1:
		newi = (b, c)
		for i in range(1, len(intervals)):
			if check_path(intervals[i], newi):
				adj[i].append(len(intervals))
			if check_path(newi, intervals[i]):
				adj[len(intervals)].append(i)
		intervals.append(newi)
	elif bfs(b, c):
		print('YES')
	else:
		print('NO')


flag = False

def main():
	intset = []
	qr = int(input())
	for i in range(qr):
		qqss = str(input())
		qqss = qqss.split(' ')
		if qqss[0] == '1':
			a = int(qqss[1])
			b = int(qqss[2])
			intset.append([a, b])
		else:
			si = int(qqss[1])
			fi = int(qqss[2])
			si -= 1
			fi -= 1
			v = [False for x in range(len(intset))]
			printIsPath(intset, si, fi, v)

def printIsPath(iset, a, b, v):
	ast = iset[a][0]
	aen = iset[a][1]
	bst = iset[b][0]
	ben = iset[b][1]
	if bst < ast < ben or bst < aen < ben:
		print('YES')
		return
	v[a] = True
	nonlocal flag
	flag = False
	for i in range(len(iset)):
		mst = iset[i][0]
		men = iset[i][1]
		if (mst < ast < men or mst < aen < men) and (not v[i]):
			if searchFinal(iset, i, b, v):
				return
	if not flag:
		print('NO')

def searchFinal(iset, i, f, v):
	v[i] = True
	if i == f:
		print('YES')
		nonlocal flag
		flag = True
		return True
	ist = iset[i][0]
	ien = iset[i][1]
	for j in range(len(iset)):
		jst = iset[j][0]
		jen = iset[j][1]
		if not v[j] and (jst < ist < jen or jst < ien < jen):
			searchFinal(iset, j, f, v)
main()


visited = [0 for i in range(110)]

def reset():
	global N, visited
	for i in range(N):
		visited[i] = 0

def dfs(s, e):
	global N, nodes, visited
	if s == e:
		return True
	if visited[s] == 1:
		return False
	visited[s] = 1
	ans = False
	for i in range(N):
		if i == s:
			continue
		one = nodes[s][0]
		two = nodes[s][1]
		three = nodes[i][0]
		four = nodes[i][1]
		if three < one and one < four or (three < two and two < four):
			ans = ans or dfs(i, e)
	return ans
nodes = []
N = 0
M = int(input())
for k in range(M):
	(com, u, v) = tuple((int(i) for i in input().split()))
	if com == 1:
		V = [u, v]
		nodes.append(V)
		N += 1
	else:
		u -= 1
		v -= 1
		reset()
		if dfs(u, v):
			print('YES')
		else:
			print('NO')


data = []
for _ in range(int(input())):
	cmd = list(map(int, input().split()))
	if cmd[0] == 1:
		data.append(cmd[1:])
	else:
		done = [False] * (len(data) + 1)
		que = [cmd[1] - 1]
		while len(que):
			p = que[0]
			del que[0]
			for (i, v) in enumerate(data):
				if (v[0] < data[p][0] < v[1] or v[0] < data[p][1] < v[1]) and (not done[i]):
					done[i] = True
					que.append(i)
		print('YES' if done[cmd[2] - 1] else 'NO')


import sys

def add_interval(interval_dict, interval_list, start, end):
	if start in interval_dict:
		if not (start, end) in interval_dict[start]:
			interval_dict[start].append((start, end))
	else:
		interval_dict[start] = [(start, end)]
	interval_list.append((start, end))

def is_path(interval_dict, visited, start, end):
	if start == end:
		return 'YES'
	if start in visited:
		return 'NO'
	visited.append(start)
	for key in interval_dict.keys():
		for next in interval_dict[key]:
			if next[0] < start[0] and start[0] < next[1] or (next[0] < start[1] and start[1] < next[1]):
				if is_path(interval_dict, visited, next, end) == 'YES':
					return 'YES'
	return 'NO'

def main():
	queries = int(input())
	interval_dict = dict()
	interval_list = []
	for query in range(queries):
		(option, x, y) = input().strip().split(' ')
		(option, x, y) = [int(option), int(x), int(y)]
		if option == 1:
			add_interval(interval_dict, interval_list, x, y)
		else:
			a = interval_list[x - 1]
			b = interval_list[y - 1]
			print(is_path(interval_dict, list(), a, b))
main()


import sys
all_intervals = list()

class Interval:

	def __init__(self, start, end):
		self.start = start
		self.end = end
		self.connected = set()

	def can_go_to(self, to_interval):
		return to_interval.start < self.start < to_interval.end or to_interval.start < self.end < to_interval.end

	def __repr__(self):
		return '({}, {} - {})'.format(self.start, self.end, self.connected)

def add_interval(interval):
	i = 1
	new_interval_num = len(all_intervals) + 1
	for existing_interval in all_intervals:
		if existing_interval.can_go_to(interval):
			existing_interval.connected.add(new_interval_num)
		if interval.can_go_to(existing_interval):
			interval.connected.add(i)
		i += 1
	all_intervals.append(interval)

def has_path(from_interval, to_interval):
	interval_queue = list()
	interval_queue.extend(from_interval.connected)
	visited = set()
	while len(interval_queue) != 0:
		next_interval_num = interval_queue.pop()
		if next_interval_num in visited:
			continue
		visited.add(next_interval_num)
		next_interval = all_intervals[next_interval_num - 1]
		if next_interval.start == to_interval.start and next_interval.end == to_interval.end:
			return True
		interval_queue.extend(next_interval.connected)
	return False
n = int(input())
for i in range(n):
	query_line = [int(item) for item in input().split(' ')]
	if query_line[0] == 1:
		interval = Interval(query_line[1], query_line[2])
		add_interval(interval)
	else:
		from_interval_num = query_line[1]
		to_interval_num = query_line[2]
		from_interval = all_intervals[from_interval_num - 1]
		to_interval = all_intervals[to_interval_num - 1]
		if has_path(from_interval, to_interval):
			print('YES')
		else:
			print('NO')


def dfs(start, end):
	visited = list()
	stack = [i_list[start]]
	while stack:
		cur = stack.pop()
		if cur not in visited:
			visited.append(cur)
			if i_list.index(cur) == end:
				return True
			for i in i_list:
				if i[0] < cur[0] < i[1] or i[0] < cur[1] < i[1]:
					stack.append(i)
	return False
num_c = int(input())
i_list = list()
for i in range(num_c):
	line = input().split()
	com = line[0]
	start = int(line[1])
	end = int(line[2])
	if com == '1':
		i_list.append([start, end])
	elif com == '2':
		if dfs(start - 1, end - 1):
			print('YES')
		else:
			print('NO')


path = []
n = int(input())
for it in range(0, n):
	data = list(map(int, input().split(' ')))
	if data[0] == 1:
		path.append(data[1:])
	else:
		vis = [False] * (len(path) + 1)
		que = [data[1] - 1]
		while len(que):
			p = que[0]
			del que[0]
			for (i, v) in enumerate(path):
				if (v[0] < path[p][0] < v[1] or v[0] < path[p][1] < v[1]) and (not vis[i]):
					vis[i] = True
					que.append(i)
		print('YES' if vis[data[2] - 1] else 'NO')


graph = {}
intervals = {}

def dfs(root, end, visited):
	visited[root] = True
	if root == end:
		return True
	try:
		for child in graph[root]:
			try:
				if visited[child]:
					pass
			except:
				if dfs(child, end, visited):
					return True
		return False
	except:
		return False
N = int(input())
cnt = 0
for _ in range(N):
	(n, a, b) = map(int, input().split())
	if n == 1:
		cnt += 1
		for (inter, index) in intervals.items():
			if a < inter[0] < b or a < inter[1] < b:
				try:
					graph[index].append(cnt)
				except:
					graph[index] = [cnt]
			if inter[0] < a < inter[1] or inter[0] < b < inter[1]:
				try:
					graph[cnt].append(index)
				except:
					graph[cnt] = [index]
		intervals[a, b] = cnt
	else:
		visited = {}
		if dfs(a, b, visited):
			print('YES')
		else:
			print('NO')


n = int(input())
l1 = []
l2 = []
hash = {}

def solve(l1, hash):
	for i in range(len(l1)):
		hash[i + 1] = set()
	for i in range(len(l1)):
		for j in range(len(l1)):
			if l1[j][1] < l1[i][1] < l1[j][2] or l1[j][1] < l1[i][2] < l1[j][2]:
				hash[i + 1].add(j + 1)
	return hash
hash_bool = {}

def bfs(hash_bool, a, b, hash):
	l = []
	l.append(a)
	hash_bool[a] = True
	while l != []:
		k = l.pop(0)
		for i in hash[k]:
			if hash_bool[i] == False:
				hash_bool[i] = True
				l.append(i)
	if hash_bool[b] == False:
		return 'NO'
	else:
		return 'YES'
for i in range(n):
	(a, b, c) = map(int, input().split())
	if a == 1:
		l1.append([a, b, c])
	else:
		hash = {}
		k = solve(l1, hash)
		for i in range(len(l1)):
			hash_bool[i + 1] = False
		d = bfs(hash_bool, b, c, k)
		print(d)


n = int(input())
s = []
ans = []

def bfs(x, y, ans):
	n = x
	while 1:
		for i in s:
			if i not in vis and (i[0] < n[0] < i[1] or i[0] < n[1] < i[1]):
				stack.append(i)
				if i == y:
					ans.append('YES')
					return ans
		if len(stack) == 0:
			ans.append('NO')
			return ans
		n = stack.pop(0)
		vis.append(n)
for i in range(n):
	(c, x, y) = map(int, input().split())
	if c == 1:
		s.append([x, y])
	else:
		vis = [s[x - 1]]
		stack = []
		ans = bfs(s[x - 1], s[y - 1], ans)
print(*ans, sep='\n')


class Graph:

	def __init__(self):
		self.ele = list()
		self.adj = list()

	def add(self, x, y):
		self.ele.append([x, y])
		self.adj.append([])
		for i in range(len(self.ele) - 1):
			if self.ele[i][0] < x < self.ele[i][1] or self.ele[i][0] < y < self.ele[i][1]:
				self.adj[len(self.ele) - 1].append(i)
			if x < self.ele[i][0] < y or x < self.ele[i][1] < y:
				self.adj[i].append(len(self.ele) - 1)

	def BFS(self, a, b):
		que = list()
		visited = list()
		que.append(a - 1)
		while len(que) != 0:
			n = que.pop()
			for i in self.adj[n]:
				if i not in visited:
					que.append(i)
			visited.append(n)
		if b - 1 in visited:
			print('YES')
		else:
			print('NO')
g = Graph()
ite = int(input())
for _ in range(ite):
	(x, y, z) = map(int, input().split())
	if x == 1:
		g.add(y, z)
	else:
		g.BFS(y, z)


import sys
from collections import defaultdict
n = int(sys.stdin.readline().split()[0])
V = []
g = defaultdict(set)
visited = set()

def dfs(a, b):
	if a == b:
		return True
	for v in g[a]:
		if v not in visited:
			visited.add(v)
			if dfs(v, b):
				return True
	return False
for _ in range(n):
	(q, x, y) = (int(i) for i in sys.stdin.readline().split())
	if q == 1:
		for (a, b) in V:
			if a < x < b or a < y < b:
				g[x, y].add((a, b))
			if x < a < y or x < b < y:
				g[a, b].add((x, y))
		V.append((x, y))
	else:
		visited.clear()
		if dfs(V[x - 1], V[y - 1]):
			print('YES')
		else:
			print('NO')


num_q = int(input().strip())

def can_a_goto_b(interval_a, interval_b):
	(a, b) = interval_a
	(x, y) = interval_b
	return x < a < y or x < b < y
nodes_to_edges = dict()
nodes_added_in_order = []
for _ in range(num_q):
	(query, a, b) = [int(i) for i in input().strip().split()]
	if query == 1:
		to_add = (a, b)
		assert nodes_to_edges.keys() == set(nodes_added_in_order)
		nodes_to_edges[to_add] = set()
		nodes_added_in_order.append(to_add)
		for n in nodes_to_edges:
			if can_a_goto_b(n, to_add):
				nodes_to_edges[n].add(to_add)
			if can_a_goto_b(to_add, n):
				nodes_to_edges[to_add].add(n)
	else:
		dest = nodes_added_in_order[b - 1]
		stack = [nodes_added_in_order[a - 1]]
		visited = set()
		while stack:
			curr = stack.pop(0)
			if curr in visited:
				continue
			if curr == dest:
				visited.add(dest)
				break
			for n in nodes_to_edges[curr]:
				stack.append(n)
			visited.add(curr)
		print('YES' if dest in visited else 'NO')


n_querries = int(input())

def has_edge(a, b, c, d):
	return c < a < d or c < b < d
querries = []
for q in range(n_querries):
	querries.append([int(x) for x in input().split()])
valid_q = list(filter(lambda x: x[0] == 1, querries))
graph = {}
print

def dfs(start, end):
	stack = []
	visited = set()
	stack.append(start)
	while len(stack) != 0:
		curr = stack.pop()
		if curr == end:
			return True
		if curr in visited:
			continue
		visited.add(curr)
		stack.extend(filter(lambda n: n not in visited, graph[curr]))
	return False
for querrie in querries:
	(type, start, end) = querrie
	if type == 1:
		graph.update({(start, end): []})
		for k in graph.keys():
			(s1, e1) = k
			if has_edge(s1, e1, start, end):
				graph[k].append((start, end))
			if has_edge(start, end, s1, e1):
				graph[start, end].append(k)
	if type == 2:
		q1 = valid_q[start - 1]
		q2 = valid_q[end - 1]
		k1 = (q1[1], q1[2])
		k2 = (q2[1], q2[2])
		if dfs(k1, k2):
			print('YES')
		else:
			print('NO')


import sys
num_queries = 0
visited = []
first = []
last = []

def dfs(start, end):
	if start == end:
		return True
	for i in range(0, num_queries):
		if visited[i] == 0:
			if first[start] > first[i] and first[start] < last[i]:
				visited[i] = 1
				if dfs(i, end):
					return True
			elif last[start] > first[i] and last[start] < last[i]:
				visited[i] = 1
				if dfs(i, end):
					return True
	return False
num_lines: sys.stdin.readline()
for line in sys.stdin:
	temp = line.split()
	temp = list(map(int, temp))
	q_type = temp[0]
	if q_type == 1:
		first.append(temp[1])
		last.append(temp[2])
		num_queries += 1
	else:
		visited = [0 for j in range(0, num_queries)]
		visited[temp[1] - 1] = 1
		if dfs(temp[1] - 1, temp[2] - 1):
			print('{}'.format('YES'))
		else:
			print('{}'.format('NO'))


import sys

class Node(object):

	def __init__(self, value):
		self.value = value
		self.edges = []
		self.visited = False
		self.cost = 200

	def add_edge(self, e):
		self.edges.append(e)

	def __lt__(self, n):
		return self.cost < n.cost

class Edge(object):

	def __init__(self, src, dest, weight):
		self.src = src
		self.dest = dest
		self.weight = weight

def dfs(src, dest):
	src.visited = True
	for i in src.edges:
		if i.dest == dest:
			return True
		elif not i.dest.visited and dfs(i.dest, dest):
			return True
	return False
n = int(input())
intervals = {}
count = 1
for i in range(n):
	line = [int(j) for j in input().split(' ')]
	if line[0] == 1:
		new_node = Node((line[1], line[2]))
		for node in intervals:
			if intervals[node].value[0] < line[1] < intervals[node].value[1] or intervals[node].value[0] < line[2] < intervals[node].value[1]:
				new_node.add_edge(Edge(new_node, intervals[node], 1))
			if line[1] < intervals[node].value[0] < line[2] or line[1] < intervals[node].value[1] < line[2]:
				intervals[node].add_edge(Edge(intervals[node], new_node, 1))
		intervals[count] = new_node
		count += 1
	else:
		if dfs(intervals[line[1]], intervals[line[2]]):
			print('YES')
		else:
			print('NO')
		for j in intervals:
			intervals[j].visited = False


def dfs(a, b, v, e):
	if a == b:
		return True
	v[a] = True
	for x in e[a]:
		if not v[x] and dfs(x, b, v, e):
			return True
	return False
(a, e) = ([], [])
for i in range(int(input())):
	(t, x, y) = map(int, input().split())
	if t == 1:
		a.append((x, y))
		e.append([])
		for (i, ai) in enumerate(a):
			if x in range(ai[0] + 1, ai[1]) or y in range(ai[0] + 1, ai[1]):
				e[-1].append(i)
			if ai[0] in range(x + 1, y) or ai[1] in range(x + 1, y):
				e[i].append(len(a) - 1)
	else:
		print('YES' if dfs(x - 1, y - 1, [False] * len(a), e) else 'NO')


class Ranges:

	def __init__(self):
		self.ranges = []

	def add_range(self, start, end):
		self.ranges.append((start, end))

	def is_path(self, start, end):
		start -= 1
		end -= 1
		lower = min(start, end)
		higher = max(start, end)
		queue = [(start, self.ranges[start])]
		seen = set()
		while len(queue) > 0:
			(idx, r) = queue.pop()
			if idx == end:
				return True
			seen.add(idx)
			reachable = [i for i in range(0, len(self.ranges)) if self._path_exists(idx, i) and i not in seen]
			reachable = list(map(lambda x: (x, self.ranges[x]), reachable))
			queue.extend(reachable)
		return False

	def _path_exists(self, x, y):
		(a, b) = self.ranges[x]
		(c, d) = self.ranges[y]
		return c < a < d or c < b < d

def main():
	nqueries = int(input())
	ranges = Ranges()
	for x in range(nqueries):
		(qtype, start, end) = map(int, input().split())
		if qtype == 1:
			ranges.add_range(start, end)
		else:
			print('YES' if ranges.is_path(start, end) else 'NO')
main()


import sys
import queue

class Node:

	def __init__(self, num, x, y):
		self.num = num
		self.weight = 0
		self.x = x
		self.y = y
		self.visited = False
		self.adjacent = set()

	def add_edge(self, v):
		self.adjacent.add(v)

def update_graph():
	for n1 in node_list:
		for n2 in node_list:
			if n1 is not n2:
				if n2.x < n1.x < n2.y or n2.x < n1.y < n2.y:
					n1.add_edge(n2)

def find_path(start, end):
	for node in node_list:
		node.visited = False
	q = queue.Queue()
	q.put(start)
	while q.qsize():
		n = q.get()
		n.visited = True
		if n is end:
			return 'YES'
		for v in n.adjacent:
			if not v.visited:
				q.put(v)
	return 'NO'
n = int(sys.stdin.readline())
count = 0
node_list = []
for i in range(n):
	(query_type, a, b) = map(int, sys.stdin.readline().split(' '))
	if query_type == 1:
		node_list.append(Node(count, a, b))
		count += 1
		update_graph()
	else:
		print(find_path(node_list[a - 1], node_list[b - 1]))


def dfs(edge_list, start, end):
	queue = [start]
	visited = [False] * len(edge_list)
	while len(queue) > 0:
		el = queue.pop()
		for i in edge_list[el]:
			if not visited[i]:
				if i == end:
					return True
				visited[i] = True
				queue.append(i)
	return False
edge_list = []
intervals = []
for _ in range(int(input())):
	(a, b, c) = map(int, input().split())
	if a == 1:
		edge_list.append([])
		intervals.append((b, c))
		for (idx, i) in enumerate(intervals):
			if i[0] < b < i[1] or i[0] < c < i[1]:
				edge_list[-1].append(idx)
			if b < i[0] < c or b < i[1] < c:
				edge_list[idx].append(len(edge_list) - 1)
	else:
		print('YES' if dfs(edge_list, b - 1, c - 1) else 'NO')


from collections import deque
nodes = {}

class Node:

	def __init__(self, x, y, nid):
		self.nid = nid
		self.x = x
		self.y = y
		self.adj = []
		self.visited = False

def c1(x, y):
	nodes[len(nodes) + 1] = Node(x, y, len(nodes) + 1)

def flood_fill(start_node):
	stack = deque()
	stack.append(start_node)
	while len(stack) > 0:
		current = stack.pop()
		current.visited = True
		for node in current.adj:
			if not node.visited:
				node.visited = True
				stack.append(node)

def try_connect(n1, n2):
	if n2.x < n1.x and n1.x < n2.y or (n2.x < n1.y and n1.y < n2.y):
		n1.adj.append(n2)

def connect(nodes):
	for (nid, node) in nodes.items():
		for (nid2, node2) in nodes.items():
			if nid != nid2:
				try_connect(node, node2)
				try_connect(node2, node)

def c2(a, b):
	for nid in nodes:
		nodes[nid].adj = []
		nodes[nid].visited = False
	connect(nodes)
	flood_fill(nodes[a])
	if nodes[b].visited:
		return True
n = int(input())
for i in range(n):
	line = [int(x) for x in input().split()]
	command = line[0]
	if command == 1:
		c1(line[1], line[2])
	else:
		print('YES' if c2(line[1], line[2]) else 'NO')


from collections import deque

def bfs(a, b, al):
	seen = set()
	q = deque()
	for (i, e) in enumerate(al[a]):
		if e > 0:
			if i == b:
				return 'YES'
			elif i not in seen:
				q.append(i)
	while len(q) > 0:
		n = q.popleft()
		seen.add(n)
		for (i, e) in enumerate(al[n]):
			if e > 0:
				if i == b:
					return 'YES'
				elif i not in seen:
					q.append(i)
	return 'NO'
numQ = int(input())
graph = []
al = [[0] * numQ for _ in range(numQ)]
idx = 0
for _ in range(numQ):
	l = [*map(int, input().split())]
	if l[0] == 1:
		graph.append([l[1], l[2]])
		for i in range(idx):
			if graph[i][0] < l[1] < graph[i][1] or graph[i][0] < l[2] < graph[i][1]:
				al[idx][i] = 1
			if l[1] < graph[i][0] < l[2] or l[1] < graph[i][1] < l[2]:
				al[i][idx] = 1
		idx += 1
	else:
		print(bfs(l[1] - 1, l[2] - 1, al))


import os
import sys
from io import BytesIO, IOBase
from collections import deque

def main():
	n = int(input())
	arr = []

	def solve(a, b):
		vis = dict()
		start = arr[a]
		end = arr[b]
		q = deque([start])
		vis[start] = 1
		while q:
			(e, f) = q.popleft()
			for item in arr:
				if item not in vis and (item[0] < e < item[1] or item[0] < f < item[1]):
					vis[item] = 1
					if item == end:
						return True
					q.append(item)
		return False
	for _ in range(n):
		(q, a, b) = map(int, input().split())
		if q == 1:
			arr.append((a, b))
		elif solve(a - 1, b - 1):
			print('YES')
		else:
			print('NO')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


import queue
num_lines = int(input())
paths = []
for i in range(num_lines):
	cur_line = input().split(' ')
	if cur_line[0] == '1':
		paths.append([int(cur_line[1]), int(cur_line[2])])
	else:
		q = queue.Queue()
		visited = [False for x in range(len(paths))]
		q.put(paths[int(cur_line[1]) - 1])
		while not q.empty():
			cur = q.get()
			for path in range(len(paths)):
				if (paths[path][0] < cur[0] < paths[path][1] or paths[path][0] < cur[1] < paths[path][1]) and (not visited[path]):
					visited[path] = True
					q.put(paths[path])
		if visited[int(cur_line[2]) - 1]:
			print('YES')
		else:
			print('NO')


def add_edge(x, y):
	global nodes, graph
	for (i, j) in enumerate(nodes):
		if j[0] < x < j[1] or j[0] < y < j[1]:
			graph[len(nodes)][i] = 1
		if x < j[0] < y or x < j[1] < y:
			graph[i][len(nodes)] = 1

def dfs(node, vis, target):
	global nodes, graph
	vis[node] = True
	if node == target:
		return True
	for i in range(len(nodes)):
		if node != i and (not vis[i]) and graph[node][i]:
			if dfs(i, vis, target):
				return True
	return False
n = int(input())
graph = [[0 for i in range(100)] for j in range(100)]
nodes = []
for i in range(n):
	l = list(map(int, input().split()))
	(x, y) = (l[1], l[2])
	if l[0] == 1:
		add_edge(x, y)
		nodes.append([x, y])
	else:
		(x, y) = (x - 1, y - 1)
		vis = [False for i in range(len(nodes))]
		if dfs(x, vis, y):
			print('YES')
		else:
			print('NO')


import sys
import queue
T = int(sys.stdin.readline())
adj_list = dict()
ids = []
for _ in range(T):
	line = sys.stdin.readline().split()
	cond = int(line[0])
	x = int(line[1])
	y = int(line[2])
	if cond == 1:
		new_interval = (x, y)
		ids.append(new_interval)
		adj_list[new_interval] = set()
		for (interval, neighbors) in adj_list.items():
			if x <= interval[0] and y >= interval[1]:
				neighbors.add(new_interval)
			elif x >= interval[0] and y <= interval[1]:
				adj_list[new_interval].add(interval)
			elif x > interval[0] and x < interval[1] or (y > interval[0] and y < interval[1]):
				neighbors.add(new_interval)
				adj_list[new_interval].add(interval)
	elif cond == 2:
		target = ids[y - 1]
		visited = set()
		bfs = queue.Queue()
		bfs.put(ids[x - 1])
		while not bfs.empty():
			interval = bfs.get()
			if interval in visited:
				continue
			visited.add(interval)
			if interval == target:
				bfs.put((-1, -1))
				break
			for neighbor in adj_list[interval]:
				bfs.put(neighbor)
		if bfs.empty():
			print('NO')
		else:
			print('YES')


from collections import deque
tests = int(input())
ad_dict = {}
dat_set = set()
for c in range(tests):
	ad_dict[c] = []
interval = 0
for t in range(tests):
	data = input().split()
	command = int(data[0])
	a = int(data[1])
	b = int(data[2])
	setToAdd = set()
	if command == 1:
		interval += 1
		node = (interval, (a, b))
		for s in dat_set:
			if s[1][0] < a < s[1][1] or s[1][0] < b < s[1][1]:
				ad_dict[interval].append(s)
				setToAdd.add(s)
			if a < s[1][0] < b or a < s[1][1] < b:
				ad_dict[s[0]].append(node)
		dat_set.add((interval, (a, b)))
	else:
		d = deque()
		visited = set()
		found = False
		d.append(a)
		visited.add(a)
		while d:
			nod = d.popleft()
			if nod == b:
				print('YES')
				found = True
				break
			for l in ad_dict[nod]:
				if l[0] not in visited:
					d.append(l[0])
					visited.add(l[0])
		if not found:
			print('NO')


from sys import stdin

def dfs(index, adj, visited):
	visited[index] = True
	for nb in adj[index]:
		if not visited[nb]:
			dfs(nb, adj, visited)

def main():
	n = int(stdin.readline())
	vertex = []
	adj = []
	for _ in range(n):
		(tt, tx, ty) = map(int, stdin.readline().split())
		if tt == 1:
			vertex.append((tx, ty))
			adj.append([])
			if len(vertex) > 1:
				for i in range(len(vertex) - 1):
					curr = vertex[i]
					if curr[0] < tx < curr[1] or curr[0] < ty < curr[1]:
						adj[-1].append(i)
					if tx < curr[0] < ty or tx < curr[1] < ty:
						adj[i].append(len(vertex) - 1)
		else:
			visited = [False] * len(vertex)
			dfs(tx - 1, adj, visited)
			if visited[ty - 1]:
				print('YES')
			else:
				print('NO')
main()


import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush
from math import ceil, floor, gcd, fabs, factorial, fmod, sqrt, inf, log
from collections import defaultdict as dd, deque, Counter as c
from itertools import combinations as comb, permutations as perm
from bisect import bisect_left as bl, bisect_right as br, bisect
mod = pow(10, 9) + 7
mod2 = 998244353

def data():
	return sys.stdin.readline().strip()

def out(var):
	sys.stdout.write(str(var))

def outln(var):
	sys.stdout.write(str(var) + '\n')

def l():
	return list(sp())

def sl():
	return list(ssp())

def sp():
	return map(int, data().split())

def ssp():
	return map(str, data().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(n, val) for j in range(m)]
n = int(data())
intervals = dd(list)
graph = dd(set)
i = 1
for _ in range(n):
	(a, b, c) = sp()
	intervals[i] = [b, c]
	if a == 1:
		for j in intervals.keys():
			(u, v) = intervals[j]
			if u < b < v and u < c < v:
				graph[i].add(j)
			elif b < u < c and b < v < c:
				graph[j].add(i)
			elif u < b < v or u < c < v or b < u < c or (b < v < c):
				graph[i].add(j)
				graph[j].add(i)
		i += 1
	else:
		d = deque()
		d.append(b)
		vis = [0] * 101
		vis[b] = 1
		while d:
			temp = d.popleft()
			if temp == c:
				outln('YES')
				break
			for child in graph[temp]:
				if not vis[child]:
					d.append(child)
					vis[child] = 1
		else:
			outln('NO')


import sys
from math import log2, floor, ceil, sqrt
from collections import deque
Ri = lambda : [int(x) for x in sys.stdin.readline().split()]
ri = lambda : sys.stdin.readline().strip()

def input():
	return sys.stdin.readline().strip()

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e):
	return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]

def ceil(x, y=1):
	return int(-(-x // y))

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST(N=None):
	return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes():
	print('Yes')

def No():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')
INF = 10 ** 18
MOD = 10 ** 9 + 7
n = int(ri())
lis = []
dic = {}
for i in range(n):
	temp = Ri()
	if temp[0] == 1:
		(x, y) = temp[1:]
		lis.append([x, y])
		dic[len(lis) - 1] = []
		for i in dic:
			(x1, y1) = lis[i]
			if x1 < x < y1 or x1 < y < y1:
				dic[len(lis) - 1].append(i)
			if x < x1 < y or x < y1 < y:
				dic[i].append(len(lis) - 1)
	else:
		(ind1, ind2) = temp[1:]
		ind1 -= 1
		ind2 -= 1
		q = deque()
		q.append(ind1)
		vis = [False] * len(lis)
		vis[ind1] = True
		flag = False
		while len(q) > 0:
			cur = q.popleft()
			if cur == ind2:
				flag = True
				break
			vis[cur] = True
			for child in dic[cur]:
				if not vis[child]:
					q.append(child)
		if flag:
			YES()
		else:
			NO()


def recursion(first, second, visited):
	global countElements, matrix, valid
	visited.add(first)
	if first == second:
		valid = True
		return
	for i in range(countElements):
		if listElements[first][i] == 1 and first != i and (i not in visited):
			recursion(i, second, visited)
numElements = int(input())
listElements = [[0] * 100 for i in range(100)]
countElements = 0
intervals = []
for i in range(numElements):
	(t, a, b) = map(int, input().split())
	if t == 1:
		intervals.append((a, b))
		for i in range(countElements):
			(c, d) = intervals[i]
			if c < a < d or c < b < d:
				listElements[countElements][i] = 1
			if a < c < b or a < d < b:
				listElements[i][countElements] = 1
		countElements += 1
	else:
		visited = set()
		valid = False
		recursion(a - 1, b - 1, visited)
		if valid:
			print('YES')
		else:
			print('NO')


(s, t, i) = ({}, [], 1)
for n in range(int(input())):
	(c, a, b) = map(int, input().split())
	if c > 1:
		print('YES' if b in s[a] else 'NO')
	else:
		s[i] = {i}
		for (j, (x, y)) in enumerate(t, 1):
			if x < a < y or x < b < y:
				s[i].update(s[j])
		r = set((j for (j, (x, y)) in enumerate(t, 1) if a < x < b or a < y < b))
		for j in range(1, len(t) + 1):
			if r & s[j]:
				s[j].update(s[i])
		t.append((a, b))
		i += 1


from sys import stdin

class Graph:

	def __init__(self):
		self.intervals = list()
		self.intervals.append(tuple())

	def add_interval(self, a, b):
		edges = set()
		for i in range(1, len(self.intervals)):
			c = self.intervals[i][0]
			d = self.intervals[i][1]
			if c < a and a < d or (c < b and b < d):
				edges.add(i)
			if a < c and c < b or (a < d and d < b):
				self.intervals[i][2].add(len(self.intervals))
		tup = (a, b, edges)
		self.intervals.append(tup)

	def connected(self, s, d):
		visited = [False] * len(self.intervals)
		queue = []
		queue.append(s)
		visited[s] = True
		while queue:
			n = queue.pop(0)
			if n == d:
				return True
			for vertex in self.intervals[n][2]:
				if visited[vertex] == False:
					queue.append(vertex)
					visited[vertex] = True
		return False

	def print_graph(self):
		for i in range(1, len(self.intervals)):
			print('{0}: {1}'.format(i, self.intervals[i]))
queries = int(stdin.readline().strip())
graph = Graph()
for i in range(queries):
	query = list(stdin.readline().strip().split())
	if int(query[0]) == 1:
		graph.add_interval(int(query[1]), int(query[2]))
	elif graph.connected(int(query[1]), int(query[2])):
		print('YES')
	else:
		print('NO')


counter = 1
queries = int(input())
visited_intervals = [0] * (queries + 1)
intervals = {}

def get_interval():
	return tuple(map(int, input().split()))

def reset_search_data():
	global queries
	global visited_intervals
	del visited_intervals
	visited_intervals = [0] * queries

def solve():
	global counter
	global visited_intervals
	for _ in range(queries):
		query = get_interval()
		if query[0] == 1:
			intervals[counter] = query
			counter += 1
		elif query[0] == 2:
			q = []
			q.append(query[1])
			reset_search_data()
			while len(q) > 0:
				q_interval = q.pop(0)
				for index in intervals:
					c = intervals[index][1]
					d = intervals[index][2]
					a = intervals[q_interval][1]
					b = intervals[q_interval][2]
					if c < a < d or c < b < d:
						if visited_intervals[index] == 0:
							visited_intervals[index] = 1
							q.append(index)
			if visited_intervals[query[2]] == 1:
				print('YES')
			else:
				print('NO')
solve()


interval_size = 0
visited = [0] * 100
nodes = []

def dfs(x, y):
	if x == y:
		return True
	if visited[x] == 1:
		return False
	visited[x] = 1
	ans = False
	for i in range(interval_size):
		same_node = i == x
		if same_node:
			continue
		a = nodes[x][0]
		b = nodes[x][1]
		c = nodes[i][0]
		d = nodes[i][1]
		can_move = c < a < d or c < b < d
		if can_move:
			ans = ans or dfs(i, y)
	return ans
n = int(input())
for k in range(n):
	(qtype, x, y) = map(int, input().split())
	if qtype == 1:
		vector = [x, y]
		nodes.append(vector)
		interval_size += 1
	elif qtype == 2:
		visited = [0] * 100
		if dfs(x - 1, y - 1):
			print('YES')
		else:
			print('NO')


class Interval:

	def __init__(self, a, b):
		self.interval_a = a
		self.interval_b = b

	def can_go(self, interval):
		return interval.interval_a < self.interval_a < interval.interval_b or interval.interval_a < self.interval_b < interval.interval_b
intervals = []
matrix = []

def dfs(a, b, visited, matrix):
	if a == b:
		return True
	ans = False
	visited[a] = True
	for i in range(len(matrix)):
		if matrix[a][i] and (not visited[i]):
			ans = ans or dfs(i, b, visited, matrix)
	return ans
for i in range(int(input())):
	(t, a, b) = list(map(int, input().split()))
	if t == 1:
		newInterval = Interval(a, b)
		intervals.append(newInterval)
		for row in range(len(matrix)):
			matrix[row].append(intervals[row].can_go(newInterval))
		matrix.append([])
		for col in range(len(matrix)):
			matrix[len(matrix) - 1].append(newInterval.can_go(intervals[col]))
	if t == 2:
		visited = []
		for i in range(len(intervals)):
			visited.append(False)
		if dfs(a - 1, b - 1, visited, matrix):
			print('YES')
		else:
			print('NO')


def dfs(G, start, target, path_exists):
	s = [start]
	visited = set([])
	while s:
		node = s.pop()
		if not node in visited:
			visited.add(node)
			(a, b) = G[node]
			for (i, (c, d)) in enumerate(G):
				if i != node:
					if c < a < d or c < b < d:
						s.append(i)
						if i == target:
							return True
n = int(input())
G = []
path_exists = {}
for _ in range(n):
	(q, a, b) = map(int, input().split())
	if q == 1:
		G.append((a, b))
	else:
		a -= 1
		b -= 1
		if dfs(G, a, b, path_exists):
			print('YES')
		else:
			print('NO')


import collections
intervals = {}
myArr = []

def check(a, b):
	return a[0] < b[0] and b[0] < a[1] or (a[0] < b[1] and b[1] < a[1])

def one():
	myInterval = (line[1], line[2])
	intervals[myInterval] = []
	myArr.append(myInterval)
	for element in intervals:
		if check(element, myInterval):
			intervals[myInterval].append(element)
		if check(myInterval, element):
			intervals[element].append(myInterval)

def two():
	start = myArr[line[1] - 1]
	end = myArr[line[2] - 1]
	q = collections.deque()
	q.append(start)
	visited = set()
	while q:
		current = q.pop()
		if current == end:
			print('YES')
			return
		if current not in visited:
			visited.add(current)
			q.extend(intervals[current])
	print('NO')
for i in range(int(input())):
	line = [int(x) for x in input().split()]
	if line[0] == 1:
		one()
	else:
		two()


def graphAdd(u, v, G):
	for (a, b) in G:
		if a < u and u < b or (a < v and v < b):
			connect(G, u, v, a, b)
		if u < a and a < v or (u < b and b < v):
			connect(G, a, b, u, v)

def connect(G, u, v, w, x):
	G[u, v][w, x] = 1

def queueSort(G, l, u, v):
	start = l[u - 1]
	visited = dict()
	visited[start] = 1
	end = l[v - 1]
	q = [start]
	while q != []:
		cur = q.pop(0)
		for (a, b) in G[cur]:
			if (a, b) == end:
				return 'YES'
			if (a, b) not in visited:
				visited[a, b] = 1
				q.append((a, b))
	return 'NO'
numTest = int(input())
G = dict()
l = list()
while numTest > 0:
	inputList = list(map(int, input().split()))
	a = inputList[0]
	b = inputList[1]
	c = inputList[2]
	if a == 1:
		G[b, c] = {}
		graphAdd(b, c, G)
		l.append((b, c))
	else:
		print(queueSort(G, l, b, c))
	numTest -= 1


def main():
	intervals = []
	visited = []
	for _ in range(int(input())):
		read_input(intervals, visited)

def read_input(intervals: list, visited: list) -> None:
	(command, x, y) = [int(x) for x in input().split(' ')]
	if command == 1:
		intervals.append((x, y))
		visited.append(False)
	else:
		for idx in range(len(visited)):
			visited[idx] = False
		if find_path(intervals, visited, x - 1, y - 1):
			print('YES')
		else:
			print('NO')

def find_path(intervals: list, visited: list, start: int, end: int) -> bool:
	if start == end:
		return True
	else:
		for x in range(len(intervals)):
			if can_move(intervals[start], intervals[x]) and (not visited[x]):
				visited[x] = True
				if find_path(intervals, visited, x, end):
					return True
	return False

def can_move(a: tuple, b: tuple) -> bool:
	if b[0] < a[0] < b[1]:
		return True
	elif b[0] < a[1] < b[1]:
		return True
	else:
		return False
main()


from heapq import heappush, heappop
import collections

class Vertex:

	def __init__(self, x, y, id):
		self.id = id
		self.range = [x, y]
		self.neighbor = []

	def intersect(self, other):
		(other_x, other_y) = other.range
		(x, y) = self.range
		return other_x < x < other_y or other_x < y < other_y

class Graph:

	def __init__(self):
		self.graph = []
		self.cnt = 1
		self.dic = {}

	def addInfo(self, x, y):
		node = Vertex(x, y, self.cnt)
		self.dic[self.cnt] = node
		self.cnt += 1
		for nei in self.graph:
			if nei.intersect(node):
				nei.neighbor.append(node)
			if node.intersect(nei):
				node.neighbor.append(nei)
		self.graph.append(node)

	def bfs(self, src, dest):
		hq = []
		seen = set()
		hq.append(self.dic[src])
		while hq:
			tmp = []
			for node in hq:
				if node.id == dest:
					return 'YES'
				elif node not in seen:
					seen.add(node)
					for nei in node.neighbor:
						if nei not in seen:
							tmp.append(nei)
			hq = tmp
		return 'NO'
n = input()
g = Graph()
for _ in range(int(n)):
	(ops, x, y) = input().strip().split()
	if int(ops) == 1:
		g.addInfo(int(x), int(y))
	else:
		print(g.bfs(int(x), int(y)))


visited = [False] * 105
p = {}

def dfs(i):
	nonlocal visited
	nonlocal p
	if visited[i] == True:
		return
	visited[i] = True
	for j in p[i]:
		dfs(j)

def main():
	nonlocal visited
	nonlocal p
	mode = 'filee'
	if mode == 'file':
		f = open('test.txt', 'r')
	get = lambda : [int(x) for x in (f.readline() if mode == 'file' else input()).split()]
	[n] = get()
	g = [[0]]
	le = 0
	for z in range(n):
		[t, x, y] = get()
		if t == 1:
			g.append([x, y])
			le += 1
			p[le] = []
			for i in range(1, le):
				[a, b] = [g[i][0], g[i][1]]
				if x < a and a < y or (x < b and b < y):
					p[i].append(le)
				if a < x and x < b or (a < y and y < b):
					p[le].append(i)
		else:
			for i in range(105):
				visited[i] = False
			dfs(x)
			print('YES' if visited[y] == True else 'NO')
	if mode == 'file':
		f.close()

def __starting_point():
	main()
__starting_point()


n = int(input())
intervals = []
for _ in range(n):
	(a, x, y) = map(int, input().split())
	if a == 1:
		intervals.append((x, y))
	else:
		(start, end) = intervals[x - 1]
		q = []
		q.append((start, end))
		found = False
		visited = [False] * len(intervals)
		visited[x - 1] = True
		while len(q):
			(a, b) = q.pop()
			for (i, el) in enumerate(intervals):
				(c, d) = el
				if el != (a, b) and (c < a < d or c < b < d) and (not visited[i]):
					if i == y - 1:
						print('YES')
						found = True
						break
					visited[i] = True
					q.append(el)
			if found:
				break
		if not found:
			print('NO')


def main():

	class interval:

		def __init__(self, a, b):
			self.a = a
			self.b = b

		def travel(self, i2):
			(a, b) = (self.a, self.b)
			(c, d) = (i2.a, i2.b)
			return c < a and a < d or (c < b and b < d)

		def __str__(self):
			return '({} {})'.format(self.a, self.b)
	from collections import defaultdict
	adj = defaultdict(set)
	vis = set()

	def dfs(i, goal):
		nonlocal vis
		if i in vis:
			return False
		if i == goal:
			return True
		vis.add(i)
		for j in intervals:
			if i.a == j.a and i.b == j.b:
				continue
			if not i.travel(j):
				continue
			if j in vis:
				continue
			if j == goal:
				return True
			if dfs(j, goal):
				return True
		return False
	intervals = []
	n = int(input())
	for i in range(n):
		(x, a, b) = map(int, input().split(' '))
		if x == 1:
			intervals.append(interval(a, b))
		else:
			f = False
			vis = set()
			if dfs(intervals[a - 1], intervals[b - 1]):
				print('YES')
			else:
				print('NO')
main()


import collections
queries = int(input())
intervals = {}
inter_order = []
for i in range(queries):
	query = [int(x) for x in input().split()]
	if query[0] == 1:
		new_inter = (query[1], query[2])
		intervals[new_inter] = []
		inter_order.append(new_inter)
		for inter in intervals:
			if inter[0] < new_inter[0] and inter[1] > new_inter[0]:
				intervals[new_inter].append(inter)
			elif inter[0] < new_inter[1] and inter[1] > new_inter[1]:
				intervals[new_inter].append(inter)
			if new_inter[0] < inter[0] and new_inter[1] > inter[0]:
				intervals[inter].append(new_inter)
			elif new_inter[0] < inter[1] and new_inter[1] > inter[1]:
				intervals[inter].append(new_inter)
	elif query[0] == 2:
		start = inter_order[query[1] - 1]
		end = inter_order[query[2] - 1]
		q = collections.deque()
		visited = set()
		q.append(start)
		while q:
			curr = q.pop()
			if curr == end:
				print('YES')
				break
			elif curr not in visited:
				visited.add(curr)
				q.extend(intervals[curr])
		else:
			print('NO')


num_queries = int(input())
intervals = []

def bfs(start, goal, intervals):
	from collections import deque
	q = deque([start])
	visited = set([start])
	while q:
		node = q.popleft()
		(a, b) = intervals[node]
		if node == goal:
			return True
		for (idx, interval) in enumerate(intervals):
			(c, d) = interval
			if idx not in visited and (c < a < d or c < b < d):
				q.append(idx)
				visited.add(idx)
	return False
for _ in range(num_queries):
	(action, start, end) = map(int, input().split())
	assert action == 1 or action == 2
	if action == 1:
		intervals.append((start, end))
	else:
		is_path = bfs(start - 1, end - 1, intervals)
		print('YES' if is_path else 'NO')


def dfs(node, destination):
	if node == destination:
		return True
	visited[node] = True
	for adj in graph[node]:
		if not visited[adj] and dfs(adj, destination):
			return True
	return False
n = int(input())
graph = [[] for _ in range(n + 1)]
intervals = []
for _ in range(n):
	(t, first, second) = map(int, input().split())
	if t == 1:
		no = len(intervals)
		for interval in intervals:
			if interval[0] < first < interval[1] or interval[0] < second < interval[1]:
				graph[no].append(interval[2])
			if first < interval[0] < second or first < interval[1] < second:
				graph[interval[2]].append(no)
		intervals.append((first, second, no))
	else:
		visited = [False] * (n + 1)
		print('YES' if dfs(first - 1, second - 1) else 'NO')


from collections import deque
from sys import stdin
N = int(stdin.readline().rstrip())
nodes = []
adj_list = []
for n in range(0, N):
	(type, a, b) = map(int, stdin.readline().rstrip().split())
	if type == 1:
		adj_list.append([])
		for index in range(0, len(nodes)):
			(c, d) = nodes[index]
			if c < a < d or c < b < d:
				adj_list[len(nodes)].append(index)
			if a < c < b or a < d < b:
				adj_list[index].append(len(nodes))
		nodes.append((a, b))
	else:
		queue = deque()
		visited = [False] * len(nodes)
		a -= 1
		b -= 1
		queue.append(a)
		path = False
		while queue:
			c = queue.popleft()
			if c == b:
				path = True
				break
			else:
				for d in adj_list[c]:
					if not visited[d]:
						queue.append(d)
						visited[d] = True
		if path:
			print('YES')
		else:
			print('NO')


n = int(input())
intervals = []
connected = []

def intersecting(interval1, interval2):
	return interval2[0] < interval1[0] < interval2[1] or interval2[0] < interval1[1] < interval2[1]

def exists_path(ind1, ind2):
	visited = set()
	q = [ind1]
	while q:
		popped = q.pop(0)
		visited.add(popped)
		for ind in connected[popped]:
			if ind == ind2:
				return True
			if ind not in visited:
				q.append(ind)
	return False
for i in range(n):
	(q, s, f) = list(map(int, input().split()))
	if q == 1:
		dests = []
		new_interval = (s, f)
		len_intervals = len(intervals)
		for i in range(len_intervals):
			if intersecting(intervals[i], new_interval):
				connected[i].append(len_intervals)
			if intersecting(new_interval, intervals[i]):
				dests.append(i)
		intervals.append(new_interval)
		connected.append(dests)
	elif exists_path(s - 1, f - 1):
		print('YES')
	else:
		print('NO')


import collections

class Node:

	def __init__(self, x, y, index):
		self.x = x
		self.y = y
		self.index = index
		self.visited = False
		self.neighbors = []

def valid(a, b, c, d):
	return c < a and a < d or (c < b and b < d)

def path(graph, i, j):
	(start, end) = (graph[i], graph[j])
	queue = collections.deque([start])
	while queue:
		node = queue.popleft()
		if node.index == end.index:
			return True
		if not node.visited:
			node.visited = True
			for neighbor in node.neighbors:
				if not neighbor.visited:
					queue.append(neighbor)
	return False
graph = []
n = int(input())
for _ in range(n):
	(q, i, j) = [int(x) for x in input().split(' ')]
	if q == 1:
		candidate = Node(i, j, len(graph))
		for node in graph:
			(i_, j_) = (node.x, node.y)
			if valid(i_, j_, i, j):
				node.neighbors.append(candidate)
			if valid(i, j, i_, j_):
				candidate.neighbors.append(node)
		graph.append(candidate)
	if q == 2:
		for node in graph:
			node.visited = False
		if path(graph, i - 1, j - 1):
			print('YES')
		else:
			print('NO')


n = int(input())
intervals = {}
idx = 0
adj = {}

def is_path(s, e):
	if s == e:
		return True
	vis[s] = 1
	for i in adj[s]:
		if not vis[i]:
			if is_path(i, e):
				return True
	return False
for i in range(n):
	(a, b, c) = map(int, input().split())
	if a == 1:
		idx += 1
		adj[idx] = []
		for j in intervals:
			(d, e) = intervals[j]
			if d < b < e or d < c < e:
				adj[idx].append(j)
			if b < d < c or b < e < c:
				adj[j].append(idx)
		intervals[idx] = (b, c)
	else:
		vis = [0] * 101
		if is_path(b, c):
			print('YES')
		else:
			print('NO')


def input_tuple(f):
	return tuple(map(f, input().rstrip().split()))

def make_edge(i1, i2, adj_list):
	(i, a, b) = i1
	(j, c, d) = i2
	if c < a < d or c < b < d:
		adj_list[i].append(j)

def dfs(curr, dest, seen, intervals):
	(i, a, b) = curr
	if i == dest:
		return True
	seen.add(i)
	for (j, c, d) in intervals:
		if j in seen:
			continue
		if c < a < d or c < b < d:
			if dfs((j, c, d), dest, seen, intervals):
				return True
	return False

def __starting_point():
	intervals = []
	num_queries = int(input().rstrip())
	i = 1
	for _ in range(num_queries):
		(t, a, b) = input_tuple(int)
		if t == 1:
			intervals.append((i, a, b))
			i += 1
		elif t == 2:
			if dfs(intervals[a - 1], b, set(), intervals):
				print('YES')
			else:
				print('NO')
__starting_point()


class interval:
	a = 0
	b = 0
	i = 0

class neighbors:
	interval = None
	edges = None
	visited = False
numQuery = int(input())
iList = []
nList = []
index = 1
for x in range(numQuery):
	inp = input().split()
	ty = int(inp[0])
	x = int(inp[1])
	y = int(inp[2])
	if ty == 1:
		newInt = interval()
		newInt.a = x
		newInt.b = y
		newInt.i = index
		newNeigh = neighbors()
		newNeigh.edges = []
		newNeigh.interval = newInt
		nList.append(newNeigh)
		index += 1
		for n in nList:
			if x < n.interval.a and n.interval.a < y or (x < n.interval.b and n.interval.b < y):
				n.edges.append(newInt)
			if n.interval.a < x and x < n.interval.b or (n.interval.a < y and y < n.interval.b):
				newNeigh.edges.append(n.interval)
	else:
		queue = []
		start = x
		stop = y
		found = False
		for n in nList:
			n.visited = False
		n = nList[start - 1]
		queue.append(n)
		while len(queue) != 0:
			curr = queue.pop(0)
			curr.visited = True
			if curr.interval.i == stop:
				found = True
				print('YES')
				break
			else:
				for e in curr.edges:
					if nList[e.i - 1].visited == False:
						queue.append(nList[e.i - 1])
		if found == False:
			print('NO')


lectura = lambda : list(map(int, input().split()))
queries = lectura()[0]
array1 = []
for i in range(0, queries):
	listaLectura = lectura()
	if listaLectura[0] == 1:
		array1.append(listaLectura[1:])
	elif listaLectura[0] == 2:
		array2 = [False] * (len(array1) + 1)
		listaR = [listaLectura[1] - 1]
		while len(listaR):
			p1 = listaR[0]
			listaR.pop(0)
			for (ordenLista, PuntosLista) in enumerate(array1):
				if (PuntosLista[0] < array1[p1][0] < PuntosLista[1] or PuntosLista[0] < array1[p1][1] < PuntosLista[1]) and (not array2[ordenLista]):
					array2[ordenLista] = True
					listaR.append(ordenLista)
		if array2[listaLectura[2] - 1] != 0:
			print('YES')
		else:
			print('NO')


def to_list(s):
	return list(map(int, s.split(' ')))

def query(q, ranges):
	start_idx = q[1] - 1
	end_idx = q[2] - 1
	queue = [start_idx]
	visited = {}
	while len(queue) > 0:
		r = queue.pop(0)
		visited[r] = True
		for i in range(0, len(ranges)):
			if not visited.get(i, False):
				r_lb = ranges[r][1]
				r_ub = ranges[r][2]
				c_lb = ranges[i][1]
				c_ub = ranges[i][2]
				if r_lb < c_ub and r_lb > c_lb or (r_ub > c_lb and r_ub < c_ub):
					if i == end_idx:
						print('YES')
						return
					else:
						queue.append(i)
	print('NO')
n = int(input())
ranges = []
queries = []
for _ in range(0, n):
	request = to_list(input())
	if request[0] == 1:
		ranges.append(request)
	elif request[0] == 2:
		query(request, ranges)


import sys
from math import sqrt
from collections import deque
input = sys.stdin.readline

def inp():
	return int(input())

def inlt():
	return list(map(int, input().split()))

def insr():
	s = input()
	return list(s[:len(s) - 1])

def invr():
	return map(int, input().split())

def canMove(a, b, c, d):
	if a > c and a < d or (b > c and b < d):
		return True
	return False

def bfs(graph, start, end):
	myQueue = deque()
	myQueue.append(start - 1)
	visited = [False] * len(graph)
	while len(myQueue) != 0:
		cur = myQueue.popleft()
		visited[cur] = True
		for adjNode in graph[cur]:
			if adjNode + 1 == end:
				return True
			if visited[adjNode] == False:
				myQueue.append(adjNode)
	return False
n = int(input())
intervals = []
graph = []
for i in range(n):
	line = inlt()
	start = line[1]
	end = line[2]
	if line[0] == 1:
		intervals.append([start, end])
		graph.append([])
		n = len(graph)
		for i in range(n - 1):
			if canMove(start, end, intervals[i][0], intervals[i][1]):
				graph[-1].append(i)
			if canMove(intervals[i][0], intervals[i][1], start, end):
				graph[i].append(n - 1)
	elif line[0] == 2:
		if bfs(graph, start, end):
			print('YES')
		else:
			print('NO')


import queue

class Interval:

	def __init__(self, num, a, b):
		self.visited = False
		self.num = num
		self.a = a
		self.b = b
		self.edges = []

	def addEdge(self, neighbor):
		self.edges.append(neighbor)

def bfs(nodes, start, end):
	for i in nodes.values():
		i.visited = False
	q = queue.Queue()
	intervals = nodes.values()
	q.put(start)
	while not q.empty():
		num = q.get()
		if num == end:
			return True
		i = nodes[num]
		if not i.visited:
			i.visited = True
			for neighbor in i.edges:
				if not nodes[neighbor].visited:
					q.put(neighbor)
	return False
count = 1
n = int(input())
nodes = dict()
for i in range(n):
	ln = input().split(' ')
	c = int(ln[1])
	d = int(ln[2])
	if ln[0] == '1':
		newInt = Interval(count, c, d)
		nodes[count] = newInt
		for interval in nodes.values():
			a = interval.a
			b = interval.b
			if c < a and a < d or (c < b and b < d):
				interval.addEdge(count)
			if a < c and c < b or (a < d and d < b):
				newInt.addEdge(interval.num)
		count += 1
	elif bfs(nodes, c, d):
		print('YES')
	else:
		print('NO')


from collections import defaultdict
a = int(input())
lines = []
for i in range(a):
	lines.append(input())
index = 0
intervals = {}
g = defaultdict(list)
for line in lines:
	(c, x, y) = map(int, line.split(' '))
	if c == 1:
		index += 1
		intervals[index] = (x, y)
		for interval in intervals:
			(ix, iy) = intervals[interval]
			if ix < x < iy or ix < y < iy:
				g[index].append(interval)
			if x < ix < y or x < iy < y:
				g[interval].append(index)
	else:
		if x not in g or y not in [item for sublist in g.values() for item in sublist]:
			print('NO')
			continue
		fringe = [x]
		visited = []
		result = 'NO'
		while len(fringe) > 0:
			cur = fringe.pop()
			if cur == y:
				result = 'YES'
				break
			visited.append(cur)
			for neighbor in g[cur]:
				if neighbor not in visited and neighbor not in fringe:
					fringe.append(neighbor)
		print(result)


import collections

def update_edges(intervals, edges, new_interval):
	new_interval_id = len(intervals)
	for (idx, interval) in enumerate(intervals):
		if interval[0] < new_interval[0] < interval[1] or interval[0] < new_interval[1] < interval[1]:
			edges[new_interval_id].append(idx)
		if new_interval[0] < interval[0] < new_interval[1] or new_interval[0] < interval[1] < new_interval[1]:
			edges[idx].append(new_interval_id)

def bfs(edges, start, target):
	seen = set()
	q = collections.deque([start])
	while len(q) != 0:
		v = q.popleft()
		if v in seen:
			continue
		if v == target:
			return 'YES'
		seen.add(v)
		for nb in edges[v]:
			q.append(nb)
	return 'NO'

def main():
	queries = int(input())
	edges = collections.defaultdict(list)
	intervals = []
	for _ in range(queries):
		(query, a, b) = map(int, input().split(' '))
		if query == 1:
			new_interval = (a, b)
			update_edges(intervals, edges, new_interval)
			intervals.append(new_interval)
		if query == 2:
			print(bfs(edges, a - 1, b - 1))
main()


read_line = lambda : map(int, input().split())
(n,) = read_line()
intervals = []

def dfs(start, end):
	visited = []
	stack = [intervals[start]]
	while stack:
		v = stack.pop()
		if v not in visited:
			visited.append(v)
			for i in intervals:
				if i[0] < v[0] < i[1] or i[0] < v[1] < i[1]:
					stack.extend([i])
			if intervals.index(v) == end:
				return True
	return False
for i in range(n):
	(option, x, y) = read_line()
	if option == 1:
		intervals.append([x, y])
	else:
		print('YES' if dfs(x - 1, y - 1) else 'NO')


import os
import sys
from math import *
from collections import *
from bisect import *
from io import BytesIO, IOBase

def vsInput():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def value():
	return tuple(map(int, input().split()))

def array():
	return [int(i) for i in input().split()]

def Int():
	return int(input())

def Str():
	return input()

def arrayS():
	return [i for i in input().split()]

def bfs(adj, s, k):
	vis = {i: False for i in adj}
	vis[s] = True
	qu = [s]
	while len(qu) != 0:
		e = qu.pop(0)
		if e == k:
			return True
		for i in adj[e]:
			if vis[i] != True:
				qu.append(i)
				vis[i] = True
	return False
adj = {}
inter = []
for _ in range(Int()):
	(q, a, b) = value()
	if q == 1:
		adj[a, b] = []
		for i in inter:
			x = i[0]
			y = i[1]
			if a > x and a < y or (b > x and b < y):
				adj[a, b].append(i)
			if x > a and x < b or (y > a and y < b):
				adj[i].append((a, b))
		inter.append((a, b))
	elif bfs(adj, inter[a - 1], inter[b - 1]):
		print('YES')
	else:
		print('NO')


n = int(input())
data = []
count = 0
ans = []
for a0 in range(n):
	(query_num, a, b) = map(int, input().split())
	if query_num == 2:
		a -= 1
		b -= 1
		solved = False
		visited = set()
		stack = []
		paths = data[a][1]
		visited.add(a)
		for path in paths:
			stack.append(path)
		while stack:
			current = stack.pop()
			if current in visited:
				continue
			if current == b:
				ans.append('YES')
				solved = True
				break
			visited.add(current)
			paths = data[current][1]
			for path in paths:
				stack.append(path)
		if not solved:
			ans.append('NO')
	else:
		data.append([(a, b), []])
		count += 1
		for i in range(len(data)):
			c = data[i][0][0]
			d = data[i][0][1]
			for j in range(len(data)):
				if i == j:
					continue
				x = data[j][0][0]
				y = data[j][0][1]
				if x < c < y or x < d < y:
					if j not in data[i][1]:
						data[i][1].append(j)
print('\n'.join((a_ for a_ in ans)))


import queue
qy = int(input())
l = []
for _ in range(qy):
	(type, x, y) = map(int, input().split(' '))
	if type == 1:
		l.append((x, y))
	elif type == 2:
		p = [[i, 0] for i in l]
		q = queue.Queue()
		curr = l[x - 1]
		q.put(curr)
		p[x - 1][1] = 1
		goal = l[y - 1]
		found = False
		while not q.empty():
			node = q.get()
			if node == goal:
				print('YES')
				found = True
				break
			count = 0
			for (el, vis) in p:
				if vis == 0:
					if node[0] < el[1] and node[0] > el[0] or (node[1] < el[1] and node[1] > el[0]):
						q.put(el)
						p[count][1] = 1
				count += 1
		if not found:
			print('NO')


def in_interval(w, x, y, z):
	if w > y and w < z or (x > y and x < z):
		return True
	else:
		return False

def step_through(a, b, c, d, temp):
	x = None
	for interval in temp:
		e = int(interval[0])
		f = int(interval[1])
		if in_interval(a, b, c, d):
			return True
		elif in_interval(a, b, e, f):
			x = interval
			temp.remove(interval)
			if step_through(e, f, c, d, temp):
				return True
	if x != None:
		temp.append(x)
	return False
n = int(input())
set_of_intervals = []
for i in range(n):
	line = input().split()
	if line[0] == '1':
		set_of_intervals.append([line[1], line[2]])
	else:
		a = int(set_of_intervals[int(line[1]) - 1][0])
		b = int(set_of_intervals[int(line[1]) - 1][1])
		c = int(set_of_intervals[int(line[2]) - 1][0])
		d = int(set_of_intervals[int(line[2]) - 1][1])
		temp = set_of_intervals[:]
		temp.pop(int(line[1]) - 1)
		if step_through(a, b, c, d, temp):
			print('YES')
		else:
			print('NO')


n = int(input())
xy = []
adjlist = []

def dfs(visit, cur, dest):
	visit[cur] = True
	if cur == dest:
		return True
	else:
		found = False
		for v in adjlist[cur]:
			if not visit[v]:
				found = found or dfs(visit, v, dest)
		return found
for tc in range(0, n):
	(q, a, b) = [int(x) - 1 for x in input().split()]
	if q == 0:
		adjlist.append([])
		for i in range(0, len(xy)):
			(x, y) = xy[i]
			if a < x < b or a < y < b:
				adjlist[i].append(len(xy))
			if x < a < y or x < b < y:
				adjlist[len(xy)].append(i)
		xy.append((a, b))
	elif q == 1:
		visit = [False for x in range(0, len(xy))]
		if dfs(visit, a, b):
			print('YES')
		else:
			print('NO')


def add(x, y, G, t):

	def include(x_from, y_from, x_to, y_to):
		if x_from > x_to and x_from < y_to:
			return True
		if y_from > x_to and y_from < y_to:
			return True
		return False
	t.append((x, y))
	index = len(t) - 1
	for i in range(index):
		if include(x, y, t[i][0], t[i][1]):
			G[index].append(i)
		if include(t[i][0], t[i][1], x, y):
			G[i].append(index)

def is_path(s, t, G):
	n = len(G)
	visited = [False for _ in range(n)]
	found = False

	def DFS_visit(u):
		nonlocal visited, G, t, found
		if u == t:
			found = True
		visited[u] = True
		for v in G[u]:
			if not visited[v]:
				DFS_visit(v)
	DFS_visit(s)
	return found
n = int(input())
t = []
G = [[] for _ in range(100)]
for _ in range(n):
	(typ, x, y) = map(int, input().split())
	if typ == 1:
		add(x, y, G, t)
	else:
		x -= 1
		y -= 1
		if is_path(x, y, G):
			print('YES')
		else:
			print('NO')


def main():
	intervals = []
	condensed = []
	index = 0
	n = int(input())
	for i in range(n):
		(query, start, end) = [int(k) for k in input().split(' ')]
		if query == 1:
			intervals.append((index, start, end))
			index += 1
		else:
			print('YES' if check_path(start, end, intervals) else 'NO')
	return 0

def check_path(source, dest, intervals):
	visited = [False] * len(intervals)
	stack = []
	stack.append(intervals[source - 1])
	while stack:
		curr = stack.pop()
		visited[curr[0]] = True
		for i in intervals:
			if not visited[i[0]]:
				if i[1] < curr[1] < i[2] or i[1] < curr[2] < i[2]:
					if i == intervals[dest - 1]:
						return True
					stack.append(i)
	return False
main()


n = int(input())
dic = {}
edges = {}
i = 0
for j in range(n):
	(x, a, b) = map(int, input().split())
	if x == 1:
		edges[i] = []
		for (key, val) in dic.items():
			if val[0] < a < val[1] or val[0] < b < val[1]:
				edges[i].append(key)
			if a < val[0] < b or a < val[1] < b:
				edges[key].append(i)
		dic[i] = (a, b)
		i += 1
	else:
		st = a - 1
		end = b - 1
		visited = [0 for k in range(i)]
		ls = [st]
		while ls:
			node = ls.pop()
			for neigh in edges[node]:
				if not visited[neigh]:
					ls.append(neigh)
			visited[node] = True
		print(['NO', 'YES'][visited[end]])


interval = []
nodes = {}
n = int(input())

def func(x, y):
	(a, b) = x
	(c, d) = y
	return c < a < d or c < b < d
for i in range(0, n):
	(t, x, y) = map(int, input().split())
	if t == 1:
		xy = (x, y)
		interval.append(xy)
		nodes[xy] = []
		for i in interval:
			if func(i, xy):
				nodes[i].append(xy)
			if func(xy, i):
				nodes[xy].append(i)
	if t == 2:
		x -= 1
		y -= 1
		a = interval[x]
		b = interval[y]
		visited = {a}
		lst = [a]
		while len(lst) > 0:
			i = lst[0]
			lst = lst[1:]
			for j in nodes[i]:
				if not j in visited:
					lst.append(j)
					visited = visited | {j}
		if b in visited:
			print('YES')
		else:
			print('NO')