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 I1 from our set to interval I2 from our set if there is a sequence of successive moves starting from I1 so that we can reach I2.

Your program should handle the queries of the following two types:

  1. "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. "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 109 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
/**
 * DA-IICT
 * Author : PARTH PATEL
 */
import java.io.*;
import java.math.*;
import java.util.*;

import static java.util.Arrays.fill;
import static java.lang.Math.*;
import static java.util.Arrays.sort;
import static java.util.Collections.sort;


public class B320 
{

	public static int mod = 1000000007;
	static FasterScanner in = new FasterScanner();
	static PrintWriter out = new PrintWriter(System.out);
	static int maxn = 102;
	static ArrayList<Integer>[] adjacencylist = new ArrayList[maxn];
	static boolean[] visited = new boolean[maxn];
	static int[] color = new int[maxn];
	static boolean bool=false;
	static int interval1,interval2;
	static class Pair
	{
		int u;
		int v;
		Pair(int u,int v)
		{
			this.u=u;
			this.v=v;
		}
	}
	public static void dfs(int vertex)
	{
		visited[vertex]=true;
		for(int i : adjacencylist[vertex])
		{
			if(!visited[i])
				dfs(i);
		}
	}
	public static void main(String[] args) {

		for(int i=1;i<=100;i++)
		{
			adjacencylist[i]=new ArrayList<>();
		}
		int queries=in.nextInt();
		int count=1;
		Pair[] intervals=new Pair[101];
		while(queries-->0)
		{
			int type=in.nextInt();
			if(type==1)
			{
				int x=in.nextInt();
				int y=in.nextInt();
				intervals[count]=new Pair(x, y);
				for(int i=1;i<=count;i++)
				{
					if((intervals[i].u<x && x<intervals[i].v)|| (intervals[i].u<y && y<intervals[i].v))
						adjacencylist[count].add(i);
					if((x<intervals[i].u && intervals[i].u<y) || (x<intervals[i].v && intervals[i].v<y))
							adjacencylist[i].add(count);
				}
				count++;
			}
			else
			{
				Arrays.fill(visited, false);
				interval1=in.nextInt();
				interval2=in.nextInt();
				dfs(interval1);
				if(visited[interval2])
					out.println("YES");
				else
					out.println("NO");
			}
		}
		out.close();

	}

	/////////////////SEGMENT TREE (BUILD-UPDATE-QUERY)/////////////////////////////
	/////////////////UPDATE FOLLOWING METHODS AS PER NEED//////////////////////////
	/*
	public static void buildsegmenttree(int node,int start,int end)
	{
		if(start==end)
		{
			// Leaf node will have a single element
			segmenttree[node]=arr[start];
		}
		else
		{
			int mid=start+(end-start)/2;
			// Recurse on the left child
			buildsegmenttree(2*node, start, mid);
			// Recurse on the right child
			buildsegmenttree(2*node+1, mid+1, end);
			// Internal node will have the sum of both of its children
			segmenttree[node]=segmenttree[2*node]+segmenttree[2*node+1];
		}
	}
	
	public static void updatesegmenttree(int node,int start,int end,int idx,int val)
	{
		if(start==end)
		{
			//Leaf Node
			arr[idx]+=val;
			segmenttree[node]+=val;
		}
		else
		{
			int mid=start+(end-start)/2;
			if(start<=idx && idx<=mid)
			{
				// If idx is in the left child, recurse on the left child
				updatesegmenttree(2*node, start, mid, idx, val);
			}
			else
			{
				// if idx is in the right child, recurse on the right child
				updatesegmenttree(2*node+1, mid+1, end, idx, val);
			}
			// Internal node will have the sum of both of its children
			segmenttree[node]=segmenttree[2*node]+segmenttree[2*node+1];
		}
	}
	
	public static long querysegmenttree(int node,int start,int end,int l,int r)
	{
		if(r<start || end<l)
		{
			// range represented by a node is completely outside the given range
			return 0;
		}
		if(l <= start && end <= r)
	    {
	        // range represented by a node is completely inside the given range
	        return segmenttree[node];
	    }
		// range represented by a node is partially inside and partially outside the given range
		int mid=start+(end-start)/2;
		long leftchild=querysegmenttree(2*node, start, mid, l, r);
		long rightchild=querysegmenttree(2*node+1, mid+1, end, l, r);
		return (leftchild+rightchild);
	}
	*/
	
	public static long pow(long x, long n, long mod) 
	{
		long res = 1;
		for (long p = x; n > 0; n >>= 1, p = (p * p) % mod) 
		{
			if ((n & 1) != 0) 
			{
				res = (res * p % mod);
			}
		}
		return res;
	}

	public static long gcd(long n1, long n2) 
	{
		long r;
		while (n2 != 0) 
		{
			r = n1 % n2;
			n1 = n2;
			n2 = r;
		}
		return n1;
	}

	public static long lcm(long n1, long n2) 
	{
		long answer = (n1 * n2) / (gcd(n1, n2));
		return answer;
	}

	static class FasterScanner 
	{
		private byte[] buf = new byte[1024];
		private int curChar;
		private int snumChars;

		public int read() 
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars) 
			{
				curChar = 0;
				try 
				{
					snumChars = System.in.read(buf);
				} catch (IOException e) 
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public String nextLine() 
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do 
			{
				res.appendCodePoint(c);
				c = read();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public String nextString() 
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do 
			{
				res.appendCodePoint(c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public long nextLong() 
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') 
			{
				sgn = -1;
				c = read();
			}
			long res = 0;
			do 
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			} 
			while (!isSpaceChar(c));
			return res * sgn;
		}

		public int nextInt() 
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') 
			{
				sgn = -1;
				c = read();
			}
			int res = 0;
			do 
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			} 
			while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n) 
		{
			int[] arr = new int[n];
			for (int i = 0; i < n; i++) 
			{
				arr[i] = nextInt();
			}
			return arr;
		}

		public long[] nextLongArray(int n) 
		{
			long[] arr = new long[n];
			for (int i = 0; i < n; i++)
			{
				arr[i] = nextLong();
			}
			return arr;
		}

		private boolean isSpaceChar(int c) 
		{
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c) 
		{
			return c == '\n' || c == '\r' || c == -1;
		}
	}

}
