#include <bits/stdc++.h>
#define Fast_cin ios::sync_with_stdio(false), cin.tie(0);
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
#define DEBUG(x) cerr << "DEBUG" << x << " >>> " << endl;
using namespace std;

typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef long long ll;

template <typename _T>
inline void read(_T &f) {
    f = 0; _T fu = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') fu = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }
    f *= fu;
}

template <typename T>
void print(T x) {
    if(x < 0) putchar('-'), x = -x;
    if(x < 10) putchar(x + 48);
    else print(x / 10), putchar(x % 10 + 48);
}

template <typename T>
void print(T x, char t) {
    print(x); putchar(t);
}

template <typename T>
struct hash_map_t {
    vector <T> v, val, nxt;
    vector <int> head;
    int mod, tot, lastv;
    T lastans;
    bool have_ans;

    hash_map_t (int md = 0) {
        head.clear(); v.clear(); val.clear(); nxt.clear(); tot = 0; mod = md;
        nxt.resize(1); v.resize(1); val.resize(1); head.resize(mod);
        have_ans = 0;
    }

    bool count(int x) {
        int u = x % mod;
        for(register int i = head[u]; i; i = nxt[i]) {
            if(v[i] == x) {
                have_ans = 1;
                lastv = x;
                lastans = val[i];
                return 1;
            }
        }
        return 0;
    }

    void ins(int x, int y) {
        int u = x % mod;
        nxt.push_back(head[u]); head[u] = ++tot;
        v.push_back(x); val.push_back(y);
    }

    int qry(int x) {
        if(have_ans && lastv == x) return lastans;
        count(x);
        return lastans;
    }
};

const int N = 1e5 + 5;

vector <int> t[N << 3];
int q[N][3];
int fa[N], l[N], r[N], L[N], R[N], pre[N << 1];
int n, big, cnt;

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }

void change(int u, int l, int r, int L, int R, int x) {
    if(l <= L && R <= r) {
        if(n >= 100) printf("a %d\n", u);
        t[u].push_back(x);
        return;
    }
    int mid = (L + R) >> 1;
    if(mid >= l) change(u << 1, l, r, L, mid, x);
    if(mid + 1 <= r) change(u << 1 | 1, l, r, mid + 1, R, x);
}

void query(int u, int l, int r, int x, int y) {
    if(n >= 100) printf("q %d\n", u);
    for(register unsigned i = 0; i < t[u].size(); i++) {
        int tmp = find(t[u][i]);
        if(tmp == y) continue;
        fa[tmp] = y;
        ::l[y] = min(::l[y], ::l[tmp]);
        ::r[y] = max(::r[y], ::r[tmp]);
    }
    t[u].clear();
    if(l == r) return;
    int mid = (l + r) >> 1;
    if(mid >= x) query(u << 1, l, mid, x, y);
    else query(u << 1 | 1, mid + 1, r, x, y);
}

int main() {
    read(n);
    for(register int i = 1; i <= n; i++) {
        for(register int j = 0; j <= 2; j++) read(q[i][j]);
        if(q[i][0] == 1) pre[++big] = q[i][1], pre[++big] = q[i][2];
    }
    sort(pre + 1, pre + big + 1);
    big = unique(pre + 1, pre + big + 1) - pre - 1;
    for(register int i = 1; i <= n; i++) {
        if(q[i][0] == 1) {
            ++cnt; fa[cnt] = cnt;
            int x = lower_bound(pre + 1, pre + big + 1, q[i][1]) - pre;
            int y = lower_bound(pre + 1, pre + big + 1, q[i][2]) - pre;
            l[cnt] = L[cnt] = x; r[cnt] = R[cnt] = y;
            query(1, 1, big, x, cnt); query(1, 1, big, y, cnt);
            if(l[cnt] + 1 >= r[cnt] - 1) change(1, l[cnt] + 1, r[cnt] - 1, 1, big, cnt);
            // if(n >= 100) printf("%d %d %d\n", cnt, l[cnt], r[cnt]);
        } else {
            int x = q[i][1], y = find(q[i][2]);
            if(n >= 100) {}
            else if(find(x) == y || (l[y] < L[x] && L[x] < r[y]) || (l[y] < R[x] && R[x] < r[y])) printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define Fast_cin ios::sync_with_stdio(false), cin.tie(0);
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
#define DEBUG(x) cerr << "DEBUG" << x << " >>> " << endl;
using namespace std;

typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef long long ll;

template <typename _T>
inline void read(_T &f) {
    f = 0; _T fu = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') fu = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }
    f *= fu;
}

template <typename T>
void print(T x) {
    if(x < 0) putchar('-'), x = -x;
    if(x < 10) putchar(x + 48);
    else print(x / 10), putchar(x % 10 + 48);
}

template <typename T>
void print(T x, char t) {
    print(x); putchar(t);
}

template <typename T>
struct hash_map_t {
    vector <T> v, val, nxt;
    vector <int> head;
    int mod, tot, lastv;
    T lastans;
    bool have_ans;

    hash_map_t (int md = 0) {
        head.clear(); v.clear(); val.clear(); nxt.clear(); tot = 0; mod = md;
        nxt.resize(1); v.resize(1); val.resize(1); head.resize(mod);
        have_ans = 0;
    }

    bool count(int x) {
        int u = x % mod;
        for(register int i = head[u]; i; i = nxt[i]) {
            if(v[i] == x) {
                have_ans = 1;
                lastv = x;
                lastans = val[i];
                return 1;
            }
        }
        return 0;
    }

    void ins(int x, int y) {
        int u = x % mod;
        nxt.push_back(head[u]); head[u] = ++tot;
        v.push_back(x); val.push_back(y);
    }

    int qry(int x) {
        if(have_ans && lastv == x) return lastans;
        count(x);
        return lastans;
    }
};

const int N = 1e5 + 5;

vector <int> t[N << 3];
int q[N][3];
int fa[N], l[N], r[N], L[N], R[N], pre[N << 1];
int n, big, cnt;

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }

void change(int u, int l, int r, int L, int R, int x) {
    if(l <= L && R <= r) {
        t[u].push_back(x);
        return;
    }
    int mid = (L + R) >> 1;
    if(mid >= l) change(u << 1, l, r, L, mid, x);
    if(mid + 1 <= r) change(u << 1 | 1, l, r, mid + 1, R, x);
}

void query(int u, int l, int r, int x, int y) {
    for(register unsigned i = 0; i < t[u].size(); i++) {
        int tmp = find(t[u][i]);
        if(n >= 100) printf("%d\n", tmp);
        if(tmp == y) continue;
        fa[tmp] = y;
        ::l[y] = min(::l[y], ::l[tmp]);
        ::r[y] = max(::r[y], ::r[tmp]);
    }
    t[u].clear();
    if(l == r) return;
    int mid = (l + r) >> 1;
    if(mid >= x) query(u << 1, l, mid, x, y);
    else query(u << 1 | 1, mid + 1, r, x, y);
}

int main() {
    read(n);
    for(register int i = 1; i <= n; i++) {
        for(register int j = 0; j <= 2; j++) read(q[i][j]);
        if(q[i][0] == 1) pre[++big] = q[i][1], pre[++big] = q[i][2];
    }
    sort(pre + 1, pre + big + 1);
    big = unique(pre + 1, pre + big + 1) - pre - 1;
    for(register int i = 1; i <= n; i++) {
        if(q[i][0] == 1) {
            ++cnt; fa[cnt] = cnt;
            int x = lower_bound(pre + 1, pre + big + 1, q[i][1]) - pre;
            int y = lower_bound(pre + 1, pre + big + 1, q[i][2]) - pre;
            l[cnt] = L[cnt] = x; r[cnt] = R[cnt] = y;
            query(1, 1, big, x, cnt); query(1, 1, big, y, cnt);
            if(l[cnt] + 1 >= r[cnt] - 1) change(1, l[cnt] + 1, r[cnt] - 1, 1, big, cnt);
            // if(n >= 100) printf("%d %d %d\n", cnt, l[cnt], r[cnt]);
        } else {
            int x = q[i][1], y = find(q[i][2]);
            if(n >= 100) {}
            else if(find(x) == y || (l[y] < L[x] && L[x] < r[y]) || (l[y] < R[x] && R[x] < r[y])) printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define Fast_cin ios::sync_with_stdio(false), cin.tie(0);
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
#define DEBUG(x) cerr << "DEBUG" << x << " >>> " << endl;
using namespace std;

typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef long long ll;

template <typename _T>
inline void read(_T &f) {
    f = 0; _T fu = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') fu = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }
    f *= fu;
}

template <typename T>
void print(T x) {
    if(x < 0) putchar('-'), x = -x;
    if(x < 10) putchar(x + 48);
    else print(x / 10), putchar(x % 10 + 48);
}

template <typename T>
void print(T x, char t) {
    print(x); putchar(t);
}

template <typename T>
struct hash_map_t {
    vector <T> v, val, nxt;
    vector <int> head;
    int mod, tot, lastv;
    T lastans;
    bool have_ans;

    hash_map_t (int md = 0) {
        head.clear(); v.clear(); val.clear(); nxt.clear(); tot = 0; mod = md;
        nxt.resize(1); v.resize(1); val.resize(1); head.resize(mod);
        have_ans = 0;
    }

    bool count(int x) {
        int u = x % mod;
        for(register int i = head[u]; i; i = nxt[i]) {
            if(v[i] == x) {
                have_ans = 1;
                lastv = x;
                lastans = val[i];
                return 1;
            }
        }
        return 0;
    }

    void ins(int x, int y) {
        int u = x % mod;
        nxt.push_back(head[u]); head[u] = ++tot;
        v.push_back(x); val.push_back(y);
    }

    int qry(int x) {
        if(have_ans && lastv == x) return lastans;
        count(x);
        return lastans;
    }
};

const int N = 1e5 + 5;

vector <int> t[N << 3];
int q[N][3];
int fa[N], l[N], r[N], L[N], R[N], pre[N << 1];
int n, big, cnt;

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }

void change(int u, int l, int r, int L, int R, int x) {
    if(l <= L && R <= r) {
        t[u].push_back(x);
        return;
    }
    int mid = (L + R) >> 1;
    if(mid >= l) change(u << 1, l, r, L, mid, x);
    if(mid + 1 <= r) change(u << 1 | 1, l, r, mid + 1, R, x);
}

void query(int u, int l, int r, int x, int y) {
    for(register unsigned i = 0; i < t[u].size(); i++) {
        int tmp = find(t[u][i]);
        if(tmp == y) continue;
        printf("%d\n", tmp);
        fa[tmp] = y;
        ::l[y] = min(::l[y], ::l[tmp]);
        ::r[y] = max(::r[y], ::r[tmp]);
    }
    t[u].clear();
    if(l == r) return;
    int mid = (l + r) >> 1;
    if(mid >= x) query(u << 1, l, mid, x, y);
    else query(u << 1 | 1, mid + 1, r, x, y);
}

int main() {
    read(n);
    for(register int i = 1; i <= n; i++) {
        for(register int j = 0; j <= 2; j++) read(q[i][j]);
        if(q[i][0] == 1) pre[++big] = q[i][1], pre[++big] = q[i][2];
    }
    sort(pre + 1, pre + big + 1);
    big = unique(pre + 1, pre + big + 1) - pre - 1;
    for(register int i = 1; i <= n; i++) {
        if(q[i][0] == 1) {
            ++cnt; fa[cnt] = cnt;
            int x = lower_bound(pre + 1, pre + big + 1, q[i][1]) - pre;
            int y = lower_bound(pre + 1, pre + big + 1, q[i][2]) - pre;
            l[cnt] = L[cnt] = x; r[cnt] = R[cnt] = y;
            query(1, 1, big, x, cnt); query(1, 1, big, y, cnt);
            if(l[cnt] + 1 >= r[cnt] - 1) change(1, l[cnt] + 1, r[cnt] - 1, 1, big, cnt);
            // if(n >= 100) printf("%d %d %d\n", cnt, l[cnt], r[cnt]);
        } else {
            int x = q[i][1], y = find(q[i][2]);
            if(n >= 100) {}
            else if(find(x) == y || (l[y] < L[x] && L[x] < r[y]) || (l[y] < R[x] && R[x] < r[y])) printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define Fast_cin ios::sync_with_stdio(false), cin.tie(0);
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
#define DEBUG(x) cerr << "DEBUG" << x << " >>> " << endl;
using namespace std;

typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef long long ll;

template <typename _T>
inline void read(_T &f) {
    f = 0; _T fu = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') fu = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }
    f *= fu;
}

template <typename T>
void print(T x) {
    if(x < 0) putchar('-'), x = -x;
    if(x < 10) putchar(x + 48);
    else print(x / 10), putchar(x % 10 + 48);
}

template <typename T>
void print(T x, char t) {
    print(x); putchar(t);
}

template <typename T>
struct hash_map_t {
    vector <T> v, val, nxt;
    vector <int> head;
    int mod, tot, lastv;
    T lastans;
    bool have_ans;

    hash_map_t (int md = 0) {
        head.clear(); v.clear(); val.clear(); nxt.clear(); tot = 0; mod = md;
        nxt.resize(1); v.resize(1); val.resize(1); head.resize(mod);
        have_ans = 0;
    }

    bool count(int x) {
        int u = x % mod;
        for(register int i = head[u]; i; i = nxt[i]) {
            if(v[i] == x) {
                have_ans = 1;
                lastv = x;
                lastans = val[i];
                return 1;
            }
        }
        return 0;
    }

    void ins(int x, int y) {
        int u = x % mod;
        nxt.push_back(head[u]); head[u] = ++tot;
        v.push_back(x); val.push_back(y);
    }

    int qry(int x) {
        if(have_ans && lastv == x) return lastans;
        count(x);
        return lastans;
    }
};

const int N = 1e5 + 5;

vector <int> t[N << 3];
int q[N][3];
int fa[N], l[N], r[N], L[N], R[N], pre[N << 1];
int n, big, cnt;

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }

void change(int u, int l, int r, int L, int R, int x) {
    if(l <= L && R <= r) {
        t[u].push_back(x);
        return;
    }
    int mid = (L + R) >> 1;
    if(mid >= l) change(u << 1, l, r, L, mid, x);
    if(mid + 1 <= r) change(u << 1 | 1, l, r, mid + 1, R, x);
}

void query(int u, int l, int r, int x, int y) {
    for(register unsigned i = 0; i < t[u].size(); i++) {
        int tmp = find(t[u][i]);
        if(tmp == y) continue;
        if(n >= 100) printf("%d\n", tmp);
        fa[tmp] = y;
        ::l[y] = min(::l[y], ::l[tmp]);
        ::r[y] = max(::r[y], ::r[tmp]);
    }
    t[u].clear();
    if(l == r) return;
    int mid = (l + r) >> 1;
    if(mid >= x) query(u << 1, l, mid, x, y);
    else query(u << 1 | 1, mid + 1, r, x, y);
}

int main() {
    read(n);
    for(register int i = 1; i <= n; i++) {
        for(register int j = 0; j <= 2; j++) read(q[i][j]);
        if(q[i][0] == 1) pre[++big] = q[i][1], pre[++big] = q[i][2];
    }
    sort(pre + 1, pre + big + 1);
    big = unique(pre + 1, pre + big + 1) - pre - 1;
    for(register int i = 1; i <= n; i++) {
        if(q[i][0] == 1) {
            ++cnt; fa[cnt] = cnt;
            int x = lower_bound(pre + 1, pre + big + 1, q[i][1]) - pre;
            int y = lower_bound(pre + 1, pre + big + 1, q[i][2]) - pre;
            l[cnt] = L[cnt] = x; r[cnt] = R[cnt] = y;
            query(1, 1, big, x, cnt); query(1, 1, big, y, cnt);
            if(l[cnt] + 1 >= r[cnt] - 1) change(1, l[cnt] + 1, r[cnt] - 1, 1, big, cnt);
            // if(n >= 100) printf("%d %d %d\n", cnt, l[cnt], r[cnt]);
        } else {
            int x = q[i][1], y = find(q[i][2]);
            if(n >= 100) {}
            else if(find(x) == y || (l[y] < L[x] && L[x] < r[y]) || (l[y] < R[x] && R[x] < r[y])) printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <algorithm>

using std::min;
using std::max;

int f[100001],n,cnt,L[100001],R[100001],Ol[100001],Or[100001],orig[200001],top;
int query[100001][3];
int find(int x){return f[x]?f[x]=find(f[x]):x;}
std::vector<int>vec[800001];
void merge(int root,int l,int r,int e,int x){
    for(auto it=vec[root].begin();it!=vec[root].end();++it){
        int tem=find(*it);
        if(tem==x)continue;
        f[tem]=x;
        L[x]=min(L[x],L[tem]);
        R[x]=max(R[x],R[tem]);
    }
    if(!vec[root].empty())vec[root].clear();
    if(l==r)return;
    if((l+r)>>1>=e)merge(root<<1,l,(l+r)>>1,e,x);
    else merge(root<<1|1,((l+r)>>1)+1,r,e,x);
}
void add(int root,int l,int r,int el,int er,int x){
    if(el>er)return;
    if(el>r||er<l)return;
    if(el<=l&&er>=r){
        vec[root].push_back(x);
        return;
    }
    add(root<<1,l,(l+r)>>1,el,er,x);
    add(root<<1|1,((l+r)>>1)+1,r,el,er,x);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d%d",&query[i][0],&query[i][1],&query[i][2]);
        if(query[i][0]==1)orig[++top]=query[i][1],orig[++top]=query[i][2];
    }
    std::sort(orig+1,orig+top+1);
    top=std::unique(orig+1,orig+top+1)-orig-1;
    for(int i=1,x,y;i<=n;i++){
        if(query[i][0]==1){
            ++cnt;
            x=std::lower_bound(orig+1,orig+top+1,query[i][1])-orig;
            y=std::lower_bound(orig+1,orig+top+1,query[i][2])-orig;
            L[cnt]=Ol[cnt]=x,R[cnt]=Or[cnt]=y;
            merge(1,1,top,x,cnt);
            merge(1,1,top,y,cnt);
            add(1,1,top,L[cnt]+1,R[cnt]-1,cnt);
        }
        else{
            y=find(query[i][2]);
            x=query[i][1];
            printf("%d %d\n", x, y);
            // if(find(x)==y||(L[y]<Ol[x]&&R[y]>Ol[x])||(L[y]<Or[x]&&R[y]>Or[x]))puts("YES");
            // else puts("NO");
        }
    }
}


#include <cstdio>
#include <vector>
#include <algorithm>

using std::min;
using std::max;

int f[100001],n,cnt,L[100001],R[100001],Ol[100001],Or[100001],orig[200001],top;
int query[100001][3];
int find(int x){return f[x]?f[x]=find(f[x]):x;}
std::vector<int>vec[800001];
void merge(int root,int l,int r,int e,int x){
    for(auto it=vec[root].begin();it!=vec[root].end();++it){
        int tem=find(*it);
        if(n >= 100) printf("%d\n", tem);
        if(tem==x)continue;
        f[tem]=x;
        L[x]=min(L[x],L[tem]);
        R[x]=max(R[x],R[tem]);
    }
    if(!vec[root].empty())vec[root].clear();
    if(l==r)return;
    if((l+r)>>1>=e)merge(root<<1,l,(l+r)>>1,e,x);
    else merge(root<<1|1,((l+r)>>1)+1,r,e,x);
}
void add(int root,int l,int r,int el,int er,int x){
    if(el>er)return;
    if(el>r||er<l)return;
    if(el<=l&&er>=r){
        vec[root].push_back(x);
        return;
    }
    add(root<<1,l,(l+r)>>1,el,er,x);
    add(root<<1|1,((l+r)>>1)+1,r,el,er,x);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d%d",&query[i][0],&query[i][1],&query[i][2]);
        if(query[i][0]==1)orig[++top]=query[i][1],orig[++top]=query[i][2];
    }
    std::sort(orig+1,orig+top+1);
    top=std::unique(orig+1,orig+top+1)-orig-1;
    for(int i=1,x,y;i<=n;i++){
        if(query[i][0]==1){
            ++cnt;
            x=std::lower_bound(orig+1,orig+top+1,query[i][1])-orig;
            y=std::lower_bound(orig+1,orig+top+1,query[i][2])-orig;
            L[cnt]=Ol[cnt]=x,R[cnt]=Or[cnt]=y;
            merge(1,1,top,x,cnt);
            merge(1,1,top,y,cnt);
            add(1,1,top,L[cnt]+1,R[cnt]-1,cnt);
            // if(n >= 100) printf("%d %d %d\n", cnt, L[cnt], R[cnt]);
        }
        else{
            y=find(query[i][2]);
            x=query[i][1];
            if(n >= 100) {}
            else if(find(x)==y||(L[y]<Ol[x]&&R[y]>Ol[x])||(L[y]<Or[x]&&R[y]>Or[x]))puts("YES");
            else puts("NO");
        }
    }
}


#include <cstdio>
#include <vector>
#include <algorithm>

using std::min;
using std::max;

int f[100001],n,cnt,L[100001],R[100001],Ol[100001],Or[100001],orig[200001],top;
int query[100001][3];
int find(int x){return f[x]?f[x]=find(f[x]):x;}
std::vector<int>vec[800001];
void merge(int root,int l,int r,int e,int x){
    for(auto it=vec[root].begin();it!=vec[root].end();++it){
        int tem=find(*it);
        if(tem==x)continue;
        f[tem]=x;
        L[x]=min(L[x],L[tem]);
        R[x]=max(R[x],R[tem]);
    }
    if(!vec[root].empty())vec[root].clear();
    if(l==r)return;
    if((l+r)>>1>=e)merge(root<<1,l,(l+r)>>1,e,x);
    else merge(root<<1|1,((l+r)>>1)+1,r,e,x);
}
void add(int root,int l,int r,int el,int er,int x){
    if(el>er)return;
    if(el>r||er<l)return;
    if(el<=l&&er>=r){
        vec[root].push_back(x);
        return;
    }
    add(root<<1,l,(l+r)>>1,el,er,x);
    add(root<<1|1,((l+r)>>1)+1,r,el,er,x);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d%d",&query[i][0],&query[i][1],&query[i][2]);
        if(query[i][0]==1)orig[++top]=query[i][1],orig[++top]=query[i][2];
    }
    std::sort(orig+1,orig+top+1);
    top=std::unique(orig+1,orig+top+1)-orig-1;
    for(int i=1,x,y;i<=n;i++){
        if(query[i][0]==1){
            ++cnt;
            x=std::lower_bound(orig+1,orig+top+1,query[i][1])-orig;
            y=std::lower_bound(orig+1,orig+top+1,query[i][2])-orig;
            if(n >= 100) printf("%d %d\n", x, y);
            L[cnt]=Ol[cnt]=x,R[cnt]=Or[cnt]=y;
            merge(1,1,top,x,cnt);
            merge(1,1,top,y,cnt);
            add(1,1,top,L[cnt]+1,R[cnt]-1,cnt);
        }
        else{
            y=find(query[i][2]);
            x=query[i][1];
            if(n >= 100) {}
            else if(find(x)==y||(L[y]<Ol[x]&&R[y]>Ol[x])||(L[y]<Or[x]&&R[y]>Or[x]))puts("YES");
            else puts("NO");
        }
    }
}


#include <bits/stdc++.h>
#define Fast_cin ios::sync_with_stdio(false), cin.tie(0);
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
#define DEBUG(x) cerr << "DEBUG" << x << " >>> " << endl;
using namespace std;

typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef long long ll;

template <typename _T>
inline void read(_T &f) {
    f = 0; _T fu = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') fu = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }
    f *= fu;
}

template <typename T>
void print(T x) {
    if(x < 0) putchar('-'), x = -x;
    if(x < 10) putchar(x + 48);
    else print(x / 10), putchar(x % 10 + 48);
}

template <typename T>
void print(T x, char t) {
    print(x); putchar(t);
}

template <typename T>
struct hash_map_t {
    vector <T> v, val, nxt;
    vector <int> head;
    int mod, tot, lastv;
    T lastans;
    bool have_ans;

    hash_map_t (int md = 0) {
        head.clear(); v.clear(); val.clear(); nxt.clear(); tot = 0; mod = md;
        nxt.resize(1); v.resize(1); val.resize(1); head.resize(mod);
        have_ans = 0;
    }

    bool count(int x) {
        int u = x % mod;
        for(register int i = head[u]; i; i = nxt[i]) {
            if(v[i] == x) {
                have_ans = 1;
                lastv = x;
                lastans = val[i];
                return 1;
            }
        }
        return 0;
    }

    void ins(int x, int y) {
        int u = x % mod;
        nxt.push_back(head[u]); head[u] = ++tot;
        v.push_back(x); val.push_back(y);
    }

    int qry(int x) {
        if(have_ans && lastv == x) return lastans;
        count(x);
        return lastans;
    }
};

const int N = 1e5 + 5;

vector <int> t[N << 3];
int q[N][3];
int fa[N], l[N], r[N], L[N], R[N], pre[N << 1];
int n, big, cnt;

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }

void change(int u, int l, int r, int L, int R, int x) {
    if(l <= L && R <= r) {
        t[u].push_back(x);
        return;
    }
    int mid = (L + R) >> 1;
    if(mid >= l) change(u << 1, l, r, L, mid, x);
    if(mid + 1 <= r) change(u << 1 | 1, l, r, mid + 1, R, x);
}

void query(int u, int l, int r, int x, int y) {
    for(register unsigned i = 0; i < t[u].size(); i++) {
        int tmp = find(t[u][i]);
        if(tmp == y) continue;
        fa[tmp] = y;
        ::l[y] = min(::l[y], ::l[tmp]);
        ::r[y] = max(::r[y], ::r[tmp]);
    }
    t[u].clear();
    if(l == r) return;
    int mid = (l + r) >> 1;
    if(mid >= x) query(u << 1, l, mid, x, y);
    else query(u << 1 | 1, mid + 1, r, x, y);
}

int main() {
    read(n);
    for(register int i = 1; i <= n; i++) {
        for(register int j = 0; j <= 2; j++) read(q[i][j]);
        if(q[i][0] == 1) pre[++big] = q[i][1], pre[++big] = q[i][2];
    }
    sort(pre + 1, pre + big + 1);
    big = unique(pre + 1, pre + big + 1) - pre - 1;
    for(register int i = 1; i <= n; i++) {
        if(q[i][0] == 1) {
            ++cnt; fa[cnt] = cnt;
            int x = lower_bound(pre + 1, pre + big + 1, q[i][1]) - pre;
            int y = lower_bound(pre + 1, pre + big + 1, q[i][2]) - pre;
            if(n >= 100) printf("%d %d\n", x, y);
            l[cnt] = L[cnt] = x; r[cnt] = R[cnt] = y;
            query(1, 1, big, x, cnt); query(1, 1, big, y, cnt);
            if(l[cnt] + 1 >= r[cnt] - 1) change(1, l[cnt] + 1, r[cnt] - 1, 1, big, cnt);
        } else {
            int x = q[i][1], y = find(q[i][2]);
            if(n >= 100) {}
            else if(find(x) == y || (l[y] < L[x] && L[x] < r[y]) || (l[y] < R[x] && R[x] < r[y])) printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define Fast_cin ios::sync_with_stdio(false), cin.tie(0);
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
#define DEBUG(x) cerr << "DEBUG" << x << " >>> " << endl;
using namespace std;

typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef long long ll;

template <typename _T>
inline void read(_T &f) {
    f = 0; _T fu = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') fu = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }
    f *= fu;
}

template <typename T>
void print(T x) {
    if(x < 0) putchar('-'), x = -x;
    if(x < 10) putchar(x + 48);
    else print(x / 10), putchar(x % 10 + 48);
}

template <typename T>
void print(T x, char t) {
    print(x); putchar(t);
}

template <typename T>
struct hash_map_t {
    vector <T> v, val, nxt;
    vector <int> head;
    int mod, tot, lastv;
    T lastans;
    bool have_ans;

    hash_map_t (int md = 0) {
        head.clear(); v.clear(); val.clear(); nxt.clear(); tot = 0; mod = md;
        nxt.resize(1); v.resize(1); val.resize(1); head.resize(mod);
        have_ans = 0;
    }

    bool count(int x) {
        int u = x % mod;
        for(register int i = head[u]; i; i = nxt[i]) {
            if(v[i] == x) {
                have_ans = 1;
                lastv = x;
                lastans = val[i];
                return 1;
            }
        }
        return 0;
    }

    void ins(int x, int y) {
        int u = x % mod;
        nxt.push_back(head[u]); head[u] = ++tot;
        v.push_back(x); val.push_back(y);
    }

    int qry(int x) {
        if(have_ans && lastv == x) return lastans;
        count(x);
        return lastans;
    }
};

const int N = 1e5 + 5;

vector <int> t[N << 3];
int q[N][3];
int fa[N], l[N], r[N], L[N], R[N], pre[N << 1];
int n, big, cnt;

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }

void change(int u, int l, int r, int L, int R, int x) {
    if(l <= L && R <= r) {
        // if(n >= 100) printf("a %d\n", u);
        t[u].push_back(x);
        return;
    }
    int mid = (L + R) >> 1;
    if(mid >= l) change(u << 1, l, r, L, mid, x);
    if(mid + 1 <= r) change(u << 1 | 1, l, r, mid + 1, R, x);
}

void query(int u, int l, int r, int x, int y) {
    // if(n >= 100) printf("q %d\n", u);
    for(register unsigned i = 0; i < t[u].size(); i++) {
        int tmp = find(t[u][i]);
        if(tmp == y) continue;
        fa[tmp] = y;
        ::l[y] = min(::l[y], ::l[tmp]);
        ::r[y] = max(::r[y], ::r[tmp]);
    }
    t[u].clear();
    if(l == r) return;
    int mid = (l + r) >> 1;
    if(mid >= x) query(u << 1, l, mid, x, y);
    else query(u << 1 | 1, mid + 1, r, x, y);
}

int main() {
    read(n);
    for(register int i = 1; i <= n; i++) {
        for(register int j = 0; j <= 2; j++) read(q[i][j]);
        if(q[i][0] == 1) pre[++big] = q[i][1], pre[++big] = q[i][2];
    }
    sort(pre + 1, pre + big + 1);
    big = unique(pre + 1, pre + big + 1) - pre - 1;
    for(register int i = 1; i <= n; i++) {
        if(q[i][0] == 1) {
            ++cnt; fa[cnt] = cnt;
            int x = lower_bound(pre + 1, pre + big + 1, q[i][1]) - pre;
            int y = lower_bound(pre + 1, pre + big + 1, q[i][2]) - pre;
            l[cnt] = L[cnt] = x; r[cnt] = R[cnt] = y;
            query(1, 1, big, x, cnt); query(1, 1, big, y, cnt);
            if(l[cnt] + 1 >= r[cnt] - 1) change(1, l[cnt] + 1, r[cnt] - 1, 1, big, cnt);
            if(n >= 100) printf("%d %d %d\n", cnt, l[cnt], r[cnt]);
        } else {
            int x = q[i][1], y = find(q[i][2]);
            if(n >= 100) {}
            else if(find(x) == y || (l[y] < L[x] && L[x] < r[y]) || (l[y] < R[x] && R[x] < r[y])) printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define Fast_cin ios::sync_with_stdio(false), cin.tie(0);
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
#define DEBUG(x) cerr << "DEBUG" << x << " >>> " << endl;
using namespace std;

typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef long long ll;

template <typename _T>
inline void read(_T &f) {
    f = 0; _T fu = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') fu = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }
    f *= fu;
}

template <typename T>
void print(T x) {
    if(x < 0) putchar('-'), x = -x;
    if(x < 10) putchar(x + 48);
    else print(x / 10), putchar(x % 10 + 48);
}

template <typename T>
void print(T x, char t) {
    print(x); putchar(t);
}

template <typename T>
struct hash_map_t {
    vector <T> v, val, nxt;
    vector <int> head;
    int mod, tot, lastv;
    T lastans;
    bool have_ans;

    hash_map_t (int md = 0) {
        head.clear(); v.clear(); val.clear(); nxt.clear(); tot = 0; mod = md;
        nxt.resize(1); v.resize(1); val.resize(1); head.resize(mod);
        have_ans = 0;
    }

    bool count(int x) {
        int u = x % mod;
        for(register int i = head[u]; i; i = nxt[i]) {
            if(v[i] == x) {
                have_ans = 1;
                lastv = x;
                lastans = val[i];
                return 1;
            }
        }
        return 0;
    }

    void ins(int x, int y) {
        int u = x % mod;
        nxt.push_back(head[u]); head[u] = ++tot;
        v.push_back(x); val.push_back(y);
    }

    int qry(int x) {
        if(have_ans && lastv == x) return lastans;
        count(x);
        return lastans;
    }
};

const int N = 1e5 + 5;

vector <int> t[N << 3];
int q[N][3];
int fa[N], l[N], r[N], L[N], R[N], pre[N << 1];
int n, big, cnt;

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }

void change(int u, int l, int r, int L, int R, int x) {
    if(l <= L && R <= r) {
        t[u].push_back(x);
        return;
    }
    int mid = (L + R) >> 1;
    if(mid >= l) change(u << 1, l, r, L, mid, x);
    if(mid + 1 <= r) change(u << 1 | 1, l, r, mid + 1, R, x);
}

void query(int u, int l, int r, int x, int y) {
    for(register unsigned i = 0; i < t[u].size(); i++) {
        int tmp = find(t[u][i]);
        if(tmp == y) continue;
        fa[tmp] = y;
        ::l[y] = min(::l[y], ::l[tmp]);
        ::r[y] = max(::r[y], ::r[tmp]);
    }
    t[u].clear();
    if(l == r) return;
    int mid = (l + r) >> 1;
    if(mid >= x) query(u << 1, l, mid, x, y);
    else query(u << 1 | 1, mid + 1, r, x, y);
}

int main() {
    read(n);
    for(register int i = 1; i <= n; i++) {
        for(register int j = 0; j <= 2; j++) read(q[i][j]);
        if(q[i][0] == 1) pre[++big] = q[i][1], pre[++big] = q[i][2];
    }
    sort(pre + 1, pre + big + 1);
    big = unique(pre + 1, pre + big + 1) - pre - 1;
    for(register int i = 1; i <= n; i++) {
        if(q[i][0] == 1) {
            ++cnt; fa[cnt] = cnt;
            int x = lower_bound(pre + 1, pre + big + 1, q[i][1]) - pre;
            int y = lower_bound(pre + 1, pre + big + 1, q[i][2]) - pre;
            l[cnt] = L[cnt] = x; r[cnt] = R[cnt] = y;
            query(1, 1, big, x, cnt); query(1, 1, big, y, cnt);
            if(l[cnt] + 1 >= r[cnt] - 1) change(1, l[cnt] + 1, r[cnt] - 1, 1, big, cnt);
        } else {
            int x = q[i][1], y = find(q[i][2]);
            printf("%d %d\n", x, y);
            // if(find(x) == y || (l[y] < L[x] && L[x] < r[y]) || (l[y] < R[x] && R[x] < r[y])) printf("YES\n");
            // else printf("NO\n");
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define Fast_cin ios::sync_with_stdio(false), cin.tie(0);
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
#define DEBUG(x) cerr << "DEBUG" << x << " >>> " << endl;
using namespace std;

typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef long long ll;

template <typename _T>
inline void read(_T &f) {
    f = 0; _T fu = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') fu = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }
    f *= fu;
}

template <typename T>
void print(T x) {
    if(x < 0) putchar('-'), x = -x;
    if(x < 10) putchar(x + 48);
    else print(x / 10), putchar(x % 10 + 48);
}

template <typename T>
void print(T x, char t) {
    print(x); putchar(t);
}

template <typename T>
struct hash_map_t {
    vector <T> v, val, nxt;
    vector <int> head;
    int mod, tot, lastv;
    T lastans;
    bool have_ans;

    hash_map_t (int md = 0) {
        head.clear(); v.clear(); val.clear(); nxt.clear(); tot = 0; mod = md;
        nxt.resize(1); v.resize(1); val.resize(1); head.resize(mod);
        have_ans = 0;
    }

    bool count(int x) {
        int u = x % mod;
        for(register int i = head[u]; i; i = nxt[i]) {
            if(v[i] == x) {
                have_ans = 1;
                lastv = x;
                lastans = val[i];
                return 1;
            }
        }
        return 0;
    }

    void ins(int x, int y) {
        int u = x % mod;
        nxt.push_back(head[u]); head[u] = ++tot;
        v.push_back(x); val.push_back(y);
    }

    int qry(int x) {
        if(have_ans && lastv == x) return lastans;
        count(x);
        return lastans;
    }
};

const int N = 1e5 + 5;

vector <int> t[N << 3];
int q[N][3];
int fa[N], l[N], r[N], L[N], R[N], pre[N << 1];
int n, big, cnt;

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }

void change(int u, int l, int r, int L, int R, int x) {
    if(l <= L && R <= r) {
        t[u].push_back(x);
        return;
    }
    int mid = (L + R) >> 1;
    if(mid >= l) change(u << 1, l, r, L, mid, x);
    if(mid + 1 <= r) change(u << 1 | 1, l, r, mid + 1, R, x);
}

void query(int u, int l, int r, int x, int y) {
    if(n >= 100) printf("%d\n", (int)t[u].size());
    for(register unsigned i = 0; i < t[u].size(); i++) {
        int tmp = find(t[u][i]);
        if(tmp == y) continue;
        fa[tmp] = y;
        ::l[y] = min(::l[y], ::l[tmp]);
        ::r[y] = max(::r[y], ::r[tmp]);
    }
    t[u].clear();
    if(l == r) return;
    int mid = (l + r) >> 1;
    if(mid >= x) query(u << 1, l, mid, x, y);
    else query(u << 1 | 1, mid + 1, r, x, y);
}

int main() {
    read(n);
    for(register int i = 1; i <= n; i++) {
        for(register int j = 0; j <= 2; j++) read(q[i][j]);
        if(q[i][0] == 1) pre[++big] = q[i][1], pre[++big] = q[i][2];
    }
    sort(pre + 1, pre + big + 1);
    big = unique(pre + 1, pre + big + 1) - pre - 1;
    for(register int i = 1; i <= n; i++) {
        if(q[i][0] == 1) {
            ++cnt; fa[cnt] = cnt;
            int x = lower_bound(pre + 1, pre + big + 1, q[i][1]) - pre;
            int y = lower_bound(pre + 1, pre + big + 1, q[i][2]) - pre;
            l[cnt] = L[cnt] = x; r[cnt] = R[cnt] = y;
            query(1, 1, big, x, cnt); query(1, 1, big, y, cnt);
            if(l[cnt] + 1 >= r[cnt] - 1) change(1, l[cnt] + 1, r[cnt] - 1, 1, big, cnt);
            // if(n >= 100) printf("%d %d %d\n", cnt, l[cnt], r[cnt]);
        } else {
            int x = q[i][1], y = find(q[i][2]);
            if(n >= 100) {}
            else if(find(x) == y || (l[y] < L[x] && L[x] < r[y]) || (l[y] < R[x] && R[x] < r[y])) printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <algorithm>

using std::min;
using std::max;

int f[100001],n,cnt,L[100001],R[100001],Ol[100001],Or[100001],orig[200001],top;
int query[100001][3];
int find(int x){return f[x]?f[x]=find(f[x]):x;}
std::vector<int>vec[800001];
void merge(int root,int l,int r,int e,int x){
    for(auto it=vec[root].begin();it!=vec[root].end();++it){
        int tem=find(*it);
        if(tem==x)continue;
        f[tem]=x;
        L[x]=min(L[x],L[tem]);
        R[x]=max(R[x],R[tem]);
    }
    if(!vec[root].empty())vec[root].clear();
    if(l==r)return;
    if((l+r)>>1>=e)merge(root<<1,l,(l+r)>>1,e,x);
    else merge(root<<1|1,((l+r)>>1)+1,r,e,x);
}
void add(int root,int l,int r,int el,int er,int x){
    if(el>er)return;
    if(el>r||er<l)return;
    if(el<=l&&er>=r){
        vec[root].push_back(x);
        return;
    }
    add(root<<1,l,(l+r)>>1,el,er,x);
    add(root<<1|1,((l+r)>>1)+1,r,el,er,x);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d%d",&query[i][0],&query[i][1],&query[i][2]);
        if(query[i][0]==1)orig[++top]=query[i][1],orig[++top]=query[i][2];
    }
    std::sort(orig+1,orig+top+1);
    top=std::unique(orig+1,orig+top+1)-orig-1;
    for(int i=1,x,y;i<=n;i++){
        if(query[i][0]==1){
            ++cnt;
            x=std::lower_bound(orig+1,orig+top+1,query[i][1])-orig;
            y=std::lower_bound(orig+1,orig+top+1,query[i][2])-orig;
            L[cnt]=Ol[cnt]=x,R[cnt]=Or[cnt]=y;
            merge(1,1,top,x,cnt);
            merge(1,1,top,y,cnt);
            add(1,1,top,L[cnt]+1,R[cnt]-1,cnt);
        }
        else{
            y=find(query[i][2]);
            x=query[i][1];
            if(n >= 100) printf("%d %d\n", x, y);
            else if(find(x)==y||(L[y]<Ol[x]&&R[y]>Ol[x])||(L[y]<Or[x]&&R[y]>Or[x]))puts("YES");
            else puts("NO");
        }
    }
}


#include <bits/stdc++.h>
#define Fast_cin ios::sync_with_stdio(false), cin.tie(0);
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
#define DEBUG(x) cerr << "DEBUG" << x << " >>> " << endl;
using namespace std;

typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef long long ll;

template <typename _T>
inline void read(_T &f) {
    f = 0; _T fu = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') fu = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }
    f *= fu;
}

template <typename T>
void print(T x) {
    if(x < 0) putchar('-'), x = -x;
    if(x < 10) putchar(x + 48);
    else print(x / 10), putchar(x % 10 + 48);
}

template <typename T>
void print(T x, char t) {
    print(x); putchar(t);
}

template <typename T>
struct hash_map_t {
    vector <T> v, val, nxt;
    vector <int> head;
    int mod, tot, lastv;
    T lastans;
    bool have_ans;

    hash_map_t (int md = 0) {
        head.clear(); v.clear(); val.clear(); nxt.clear(); tot = 0; mod = md;
        nxt.resize(1); v.resize(1); val.resize(1); head.resize(mod);
        have_ans = 0;
    }

    bool count(int x) {
        int u = x % mod;
        for(register int i = head[u]; i; i = nxt[i]) {
            if(v[i] == x) {
                have_ans = 1;
                lastv = x;
                lastans = val[i];
                return 1;
            }
        }
        return 0;
    }

    void ins(int x, int y) {
        int u = x % mod;
        nxt.push_back(head[u]); head[u] = ++tot;
        v.push_back(x); val.push_back(y);
    }

    int qry(int x) {
        if(have_ans && lastv == x) return lastans;
        count(x);
        return lastans;
    }
};

const int N = 1e5 + 5;

vector <int> t[N << 3];
int q[N][3];
int fa[N], l[N], r[N], L[N], R[N], pre[N << 1];
int n, big, cnt;

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }

void change(int u, int l, int r, int L, int R, int x) {
    if(l <= L && R <= r) {
        t[u].push_back(x);
        return;
    }
    int mid = (L + R) >> 1;
    if(mid >= l) change(u << 1, l, r, L, mid, x);
    if(mid + 1 <= r) change(u << 1 | 1, l, r, mid + 1, R, x);
}

void query(int u, int l, int r, int x, int y) {
    for(register unsigned i = 0; i < t[u].size(); i++) {
        int tmp = find(t[u][i]);
        if(tmp == y) continue;
        fa[tmp] = y;
        ::l[y] = min(::l[y], ::l[tmp]);
        ::r[y] = max(::r[y], ::r[tmp]);
    }
    t[u].clear();
    if(l == r) return;
    int mid = (l + r) >> 1;
    if(mid >= x) query(u << 1, l, mid, x, y);
    else query(u << 1 | 1, mid + 1, r, x, y);
}

int main() {
    read(n);
    for(register int i = 1; i <= n; i++) {
        for(register int j = 0; j <= 2; j++) read(q[i][j]);
        if(q[i][0] == 1) pre[++big] = q[i][1], pre[++big] = q[i][2];
    }
    sort(pre + 1, pre + big + 1);
    big = unique(pre + 1, pre + big + 1) - pre - 1;
    for(register int i = 1; i <= n; i++) {
        if(q[i][0] == 1) {
            ++cnt; fa[cnt] = cnt;
            int x = lower_bound(pre + 1, pre + big + 1, q[i][1]) - pre;
            int y = lower_bound(pre + 1, pre + big + 1, q[i][2]) - pre;
            l[cnt] = L[cnt] = x; r[cnt] = R[cnt] = y;
            query(1, 1, big, x, cnt); query(1, 1, big, y, cnt);
            if(l[cnt] + 1 >= r[cnt] - 1) change(1, l[cnt] + 1, r[cnt] - 1, 1, big, cnt);
        } else {
            int x = q[i][1], y = find(q[i][2]);
            if(n >= 100) printf("%d %d\n", x, y);
            else if(find(x) == y || (l[y] < L[x] && L[x] < r[y]) || (l[y] < R[x] && R[x] < r[y])) printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}


#include <bits/stdc++.h>
typedef long long int ll;
typedef long double ld;
#define pb push_back
#define pii pair < int , int >
#define F first
#define S second
#define endl '\n'
#define int long long
#define sync ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#define kill(x) return cout<<x<<'\n', 0;
using namespace std;
const int N=2e5+100;
ll par[N];
ll lf[N],rt[N];
ll getpar(ll v){
    if (par[v]==v) return v;
    return par[v]=getpar(par[v]);
}
set <int> seg[N*4];
void add(ll nod,ll l,ll r,ll L,ll R,ll val){
    if (l>=R || L>=r) return ;
    if (l>=L && r<=R){
        seg[nod].insert(val);
        return ;
    }
    ll mid=(r+l)/2;
    add(nod*2,l,mid,L,R,val);
    add(nod*2+1,mid,r,L,R,val);
}
void del(ll nod,ll l,ll r,ll L,ll R,ll val){
    if (l>=R || L>=r) return ;
    if (l>=L && r<=R){
        seg[nod].erase(val);
        return ;
    }
    ll mid=(r+l)/2;
    del(nod*2,l,mid,L,R,val);
    del(nod*2+1,mid,r,L,R,val);
}
void merg(ll x,ll y){
    x=getpar(x);
    y=getpar(y);
    del(1,1,N,lf[y]+1,rt[y],y);
    del(1,1,N,lf[x]+1,rt[x],x);
    par[x]=y;
    lf[y]=min(lf[y],lf[x]);
    rt[y]=max(rt[y],rt[x]);
    add(1,1,N,lf[y]+1,rt[y],y);
}
vector <pii> a;
void get(ll nod,ll l,ll r,ll id,ll x){

    for (auto u : seg[nod]){
        ll z=u;
        a.pb({x,z});
    }
    if (r-l==1) return ;
    ll mid=(r+l)/2;
    if (mid>id) get(nod*2,l,mid,id,x);
    else get(nod*2+1,mid,r,id,x);
}
map <int,int> mp;
vector <int> com;
pii W[N];
int32_t main(){
    ll n;
    cin >> n;
    vector <pair <int,pii> > q;
    ll cnt=0;
    for (int i=0;i<n;i++){
        ll t,l,r;
        cin >> t >> l >> r;
        q.pb({t,{l,r}});
        if (t==1){
            com.pb(l);
            com.pb(r);
        }
    }
    sort(com.begin(),com.end());
    com.resize(unique(com.begin(),com.end())-com.begin());
    for (int i=0;i<com.size();i++){
        mp[com[i]]=i+1;
    }
    for (int i=0;i<q.size();i++){
        if (q[i].F==1){
            cnt++;
            par[cnt]=cnt;
            q[i].S.F=mp[q[i].S.F];
            q[i].S.S=mp[q[i].S.S];
            ll l=q[i].S.F;
            ll r=q[i].S.S;
            W[cnt]={l,r};
            lf[cnt]=l;
            rt[cnt]=r;
            a.clear();
            get(1,1,N,l,cnt);
            get(1,1,N,r,cnt);
            add(1,1,N,lf[cnt]+1,rt[cnt],cnt);
            for (auto u : a){
                merg(u.F,u.S);
            }
        }
        else{
            ll u=q[i].S.F,v=q[i].S.S;
            u=getpar(u);
            v=getpar(v);
            if (u==v || (lf[v]<W[u].F && rt[v]>W[u].S) || (lf[v]<W[u].S && rt[v]>W[u].S)){
                cout << "YES" << endl;
            }
            else{
                cout << "NO" << endl;
            }
        }
    }
}


#include <bits/stdc++.h>
typedef int ll;
typedef long double ld;
#define pb push_back
#define pii pair < int , int >
#define F first
#define S second
#define endl '\n'
//#define int long long
#define sync ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#define kill(x) return cout<<x<<'\n', 0;
using namespace std;
const int N=2e5+100;
ll par[N];
ll lf[N],rt[N];
ll getpar(ll v){
    if (par[v]==v) return v;
    return par[v]=getpar(par[v]);
}
vector <int> seg[N*4];
void add(ll nod,ll l,ll r,ll L,ll R,ll val){
    if (l>=R || L>=r) return ;
    if (l>=L && r<=R){
        seg[nod].pb(val);
        return ;
    }
    ll mid=(r+l)/2;
    add(nod*2,l,mid,L,R,val);
    add(nod*2+1,mid,r,L,R,val);
}
void merg(ll x,ll y){
    x=getpar(x);
    y=getpar(y);
    par[x]=y;
    lf[y]=min(lf[y],lf[x]);
    rt[y]=max(rt[y],rt[x]);
    add(1,1,N,lf[y]+1,rt[y],y);
}
vector <pii> a;
void get(ll nod,ll l,ll r,ll id,ll x){
 //   vector <int> d;
    for (auto u : seg[nod]){
        ll z=u;
        if (getpar(z)!=u) continue;
        //d.pb(z);
        a.pb({x,z});
    }
    seg[nod].clear();
    if (r-l==1) return ;
    ll mid=(r+l)/2;
    if (mid>id) get(nod*2,l,mid,id,x);
    else get(nod*2+1,mid,r,id,x);
}
map <int,int> mp;
vector <int> com;
pii W[N];
int32_t main(){
    ll n;
    cin >> n;
    vector <pair <int,pii> > q;
    ll cnt=0;
    for (int i=0;i<n;i++){
        ll t,l,r;
        cin >> t >> l >> r;
        q.pb({t,{l,r}});
        if (t==1){
            com.pb(l);
            com.pb(r);
        }
    }
    sort(com.begin(),com.end());
    com.resize(unique(com.begin(),com.end())-com.begin());
    for (int i=0;i<com.size();i++){
        mp[com[i]]=i+1;
    }
    for (int i=0;i<q.size();i++){
        if (q[i].F==1){
            cnt++;
            par[cnt]=cnt;
            q[i].S.F=mp[q[i].S.F];
            q[i].S.S=mp[q[i].S.S];
            ll l=q[i].S.F;
            ll r=q[i].S.S;
            W[cnt]={l,r};
            lf[cnt]=l;
            rt[cnt]=r;
            a.clear();
            get(1,1,N,l,cnt);
            get(1,1,N,r,cnt);
            add(1,1,N,lf[cnt]+1,rt[cnt],cnt);
            for (auto u : a){
                merg(u.F,u.S);
            }
        }
        else{
            ll u=q[i].S.F,v=q[i].S.S;
            u=getpar(u);
            v=getpar(v);
            if (u==v || (lf[v]<W[u].F && rt[v]>W[u].S) || (lf[v]<W[u].S && rt[v]>W[u].S)){
                cout << "YES" << endl;
            }
            else{
                cout << "NO" << endl;
            }
        }
    }
}


#include <bits/stdc++.h>
typedef int ll;
typedef long double ld;
#define pb push_back
#define pii pair < int , int >
#define F first
#define S second
#define endl '\n'
//#define int long long
#define sync ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#define kill(x) return cout<<x<<'\n', 0;
using namespace std;
const int N=2e5+100;
ll par[N];
ll lf[N],rt[N];
ll getpar(ll v){
    if (par[v]==v) return v;
    return par[v]=getpar(par[v]);
}
vector <int> seg[N*4];
void add(ll nod,ll l,ll r,ll L,ll R,ll val){
    if (l>=R || L>=r) return ;
    if (l>=L && r<=R){
        seg[nod].pb(val);
        return ;
    }
    ll mid=(r+l)/2;
    add(nod*2,l,mid,L,R,val);
    add(nod*2+1,mid,r,L,R,val);
}
void merg(ll x,ll y){
    x=getpar(x);
    y=getpar(y);
    par[x]=y;
    lf[y]=min(lf[y],lf[x]);
    rt[y]=max(rt[y],rt[x]);
    add(1,1,N,lf[y]+1,rt[y],y);
}
vector <pii> a;
void get(ll nod,ll l,ll r,ll id,ll x){
    vector <int> d;
    for (auto u : seg[nod]){
        ll z=u;
        if (getpar(z)!=u) continue;
        d.pb(z);
        a.pb({x,z});
    }
    seg[nod]=d;
    if (r-l==1) return ;
    ll mid=(r+l)/2;
    if (mid>id) get(nod*2,l,mid,id,x);
    else get(nod*2+1,mid,r,id,x);
}
map <int,int> mp;
vector <int> com;
pii W[N];
int32_t main(){
    ll n;
    cin >> n;
    vector <pair <int,pii> > q;
    ll cnt=0;
    for (int i=0;i<n;i++){
        ll t,l,r;
        cin >> t >> l >> r;
        q.pb({t,{l,r}});
        if (t==1){
            com.pb(l);
            com.pb(r);
        }
    }
    sort(com.begin(),com.end());
    com.resize(unique(com.begin(),com.end())-com.begin());
    for (int i=0;i<com.size();i++){
        mp[com[i]]=i+1;
    }
    for (int i=0;i<q.size();i++){
        if (q[i].F==1){
            cnt++;
            par[cnt]=cnt;
            q[i].S.F=mp[q[i].S.F];
            q[i].S.S=mp[q[i].S.S];
            ll l=q[i].S.F;
            ll r=q[i].S.S;
            W[cnt]={l,r};
            lf[cnt]=l;
            rt[cnt]=r;
            a.clear();
            get(1,1,N,l,cnt);
            get(1,1,N,r,cnt);
            add(1,1,N,lf[cnt]+1,rt[cnt],cnt);
            for (auto u : a){
                merg(u.F,u.S);
            }
        }
        else{
            ll u=q[i].S.F,v=q[i].S.S;
            u=getpar(u);
            v=getpar(v);
            if (u==v || (lf[v]<W[u].F && rt[v]>W[u].S) || (lf[v]<W[u].S && rt[v]>W[u].S)){
                cout << "YES" << endl;
            }
            else{
                cout << "NO" << endl;
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define oo 0x3f3f3f3f
#define mp make_pair
#define fi first
#define se second
#define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
#define FO(i,a,b) for(int i=a;i<=b;++i)
#define FD(i,a,b) for(int i=a;i>=b;--i)
#define FE(i,G,x) for(int i=G.h[x];~i;i=G.v[i].nxt)
typedef long long LL;
typedef pair<int, int> PII;

template <class T> inline bool chkmin(T& x, T y) { return x > y ? x = y, true : false; }
template <class T> inline bool chkmax(T& x, T y) { return x < y ? x = y, true : false; }

inline LL read(void){
    LL x,f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if (ch=='-') f=-1;
    for(x=0;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    return x*f;
}

#define N 100005
struct Seg{	int d[2],x[2],y[2],s[2],used,sz,w; } T[N*2];
struct cmp{
	int cnt;cmp(int _):cnt(_){}
	bool operator()(int x,int y){ return T[x].d[cnt]<T[y].d[cnt]; }
};

#define LS T[rt].s[0]
#define RS T[rt].s[1]
#define MID (l+r>>1)
#define FAC 0.8
int n,x,y,X0,Y0,X1,Y1,rt,z,cnt,op,dcnt,v[N];
int X,Y,XX[N],YY[N],fa[N];
vector<int> V;

inline int alloc(int x,int y,int z){
	++cnt;
	T[cnt].d[0]=T[cnt].x[0]=T[cnt].x[1]=x;
	T[cnt].d[1]=T[cnt].y[0]=T[cnt].y[1]=y;
	T[cnt].w=z;T[cnt].sz=1;T[cnt].used=0;
	return cnt;
}
inline void pushup(int rt){
	int now;
	if (!T[rt].used){
		T[rt].x[0]=T[rt].x[1]=T[rt].d[0];
		T[rt].y[0]=T[rt].y[1]=T[rt].d[1];
		T[rt].sz=1;
	}else{
		T[rt].x[1]=T[rt].y[1]=-2e9;
		T[rt].x[0]=T[rt].y[0]=2e9;
		T[rt].sz=0;
	}
	if (now=LS){
		chkmin(T[rt].x[0],T[now].x[0]);chkmin(T[rt].y[0],T[now].y[0]);
		chkmax(T[rt].x[1],T[now].x[1]);chkmax(T[rt].y[1],T[now].y[1]);
		T[rt].sz+=T[now].sz;
	}
	if (now=RS){
		chkmin(T[rt].x[0],T[now].x[0]);chkmin(T[rt].y[0],T[now].y[0]);
		chkmax(T[rt].x[1],T[now].x[1]);chkmax(T[rt].y[1],T[now].y[1]);
		T[rt].sz+=T[now].sz;
	}
}
inline bool check(int x){ return T[x].x[0]<=X1&&T[x].x[1]>=X0&&T[x].y[0]<=Y1&&T[x].y[1]>=Y0; }
void dfs(int rt){ if (!rt) return ;if (!T[rt].used) v[++dcnt]=rt;dfs(LS);dfs(RS); }
int build(int l,int r,int d){
	nth_element(v+l,v+MID,v+r+1,cmp(d));
	int rt=v[MID];
	T[rt].x[0]=T[rt].x[1]=T[rt].d[0];
	T[rt].y[0]=T[rt].y[1]=T[rt].d[1];
	T[rt].sz=1;T[rt].used=0;LS=RS=0;
	if (MID!=l) LS=build(l,MID-1,d^1);
	if (MID!=r) RS=build(MID+1,r,d^1);
	pushup(rt);
	return rt;
}

int ins(int rt,int now,int d){
	if (!rt) return now;
	int &nx=T[rt].s[T[now].d[d]>=T[rt].d[d]];
	nx=ins(nx,now,d^1);
	if (T[nx].sz>T[rt].sz*FAC){ dcnt=0;dfs(rt);rt=build(1,dcnt,d); }
	pushup(rt);
	return rt;
}
void dfs1(int rt){
	if (!rt) return ;
	if (!T[rt].used) T[rt].used=1,V.push_back(T[rt].w);
	dfs1(LS);dfs1(RS);
}
void query(int& rt){
	if (!check(rt)) return ;
	if (T[rt].x[0]>=X0&&T[rt].x[1]<=X1&&T[rt].y[0]>=Y0&&T[rt].y[1]<=Y1) { dfs1(rt);rt=0; return ; }
	if (T[rt].d[0]>=X0&&T[rt].d[0]<=X1&&T[rt].d[1]>=Y0&&T[rt].d[1]<=Y1&&!T[rt].used){
		T[rt].used=1;V.push_back(T[rt].w);
	}
	if (LS) query(LS);if (RS) query(RS);
	pushup(rt);
}
int find(int x){ return fa[x]==x?x:(fa[x]=find(fa[x])); }

int main(void){
	int q=read();
	while (q--){
		op=read();
		if (op==1){
			++n;fa[n]=n;
			XX[n]=X=read();YY[n]=Y=read();V.clear();
			X0=-2e9;X1=X-1;Y0=X+1;Y1=Y-1;if (rt)query(rt);//cout<<V.size()<<endl;
			X0=X+1;X1=Y-1;Y0=Y+1;Y1=2e9;if (rt)query(rt);//cout<<V.size()<<endl;
			X0=-2e9;X1=X;Y0=Y;Y1=2e9;if (rt)query(rt);//cout<<V.size()<<endl;
			int z=V.size();
			for (int i=0;i<z;++i){
				fa[find(V[i])]=n;
				chkmin(XX[n],XX[V[i]]);
				chkmax(YY[n],YY[V[i]]);
			}
			rt=ins(rt,alloc(XX[n],YY[n],n),0);
		}else{
			X=read();Y=read();
			X=find(X);Y=find(Y);
			if (X==Y||XX[X]>XX[Y]&&XX[X]<YY[Y]||YY[X]>XX[Y]&&YY[X]<YY[Y])
				puts("YES");
			else puts("NO");
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define maxn 300010
#define ll long long
#define db double
#define vi vector<int>
#define pb push_back
#define mod 998244353
#define pi pair<int, int>
#define fi first
#define se second
#define mp make_pair
ll ksm(ll a, ll b) {
   if (!b) return 1;
   ll ns = ksm(a, b >> 1);
   ns = ns * ns % mod;
   if (b & 1) ns = ns * a % mod;
   return ns;
}
// head
int t, tp[maxn], a[maxn], b[maxn];
int fa[maxn], vis[maxn];
pi seg[maxn];
int gfa(int a) {
	if (fa[a] == a) return a;
	return fa[a] = gfa(fa[a]);
}
struct ST {
	int l, r;
	ST *ch[2];
	vi tr;
}p[maxn << 1], *root;
int stcnt = 0;
void bdtree(ST *a, int l, int r) {
	a->l = l, a->r = r;
	if (l == r) return;
	int mid = (l + r) >> 1;
	a->ch[0] = &p[stcnt++], a->ch[1] = &p[stcnt++];
	bdtree(a->ch[0], l, mid), bdtree(a->ch[1], mid + 1, r);
}
void ch(ST *a, int l, int r, int id) {
	if (l > r) return ;
	if (a->l == l && a->r == r) {
		a->tr.pb(id);
		return ;
	}
	int mid = (a->l + a->r) >> 1;
	if (r <= mid) ch(a->ch[0], l, r, id);
	else if (l > mid) ch(a->ch[1], l, r, id);
	else ch(a->ch[0], l, mid, id),
		ch(a->ch[1], mid + 1, r, id);
}
vi res;
void q(ST *a, int pl) {
	res.insert(res.end(), a->tr.begin(), a->tr.end());
	a->tr.clear();
	if (a->l == a->r) return ;
	int mid = (a->l + a->r) >> 1;
	if (pl <= mid) q(a->ch[0], pl);
	else q(a->ch[1], pl);
}
pi re[maxn];
int id[maxn];
int idcnt = 0, ncnt = 0;
int main() {
	for (int i = 0; i < maxn; i++)
		fa[i] = i;
	int n;
	cin >> n;
	vi st;
	for (int i = 1; i <= n; i++)
		scanf("%d%d%d", &tp[i], &a[i], &b[i]),
		st.pb(a[i]), st.pb(b[i]);

	sort(st.begin(), st.end());
	for (int i = 1; i <= n; i++)
		if (tp[i] == 1)
			a[i] = lower_bound(st.begin(), st.end(), a[i]) - st.begin(),
			b[i] = lower_bound(st.begin(), st.end(), b[i]) - st.begin();
	root = &p[stcnt++];
	bdtree(root, 0, st.size());
	for (int i = 1; i <= n; i++) {
		if (tp[i] == 2) {
			int ans = 0;
			int ns = gfa(id[b[i]]);
			if (seg[ns].fi < re[a[i]].fi && seg[ns].se > re[a[i]].fi) ans = 1;
			if (seg[ns].fi < re[a[i]].se && seg[ns].se > re[a[i]].se) ans = 1;
			if (ans) printf("YES\n");
			else printf("NO\n");
		}
		else {
			re[++ncnt] = mp(a[i], b[i]);
			id[i] = ++idcnt;
			seg[idcnt] = mp(a[i], b[i]);
			q(root, a[i]),
			q(root, b[i]);
			res.pb(idcnt);
			++idcnt;
			int nl = 1e9, nr = -1e9;
			for (int i = 0; i < res.size(); i++) {
				int nid = res[i];
				if (vis[nid]) continue;
				vis[nid] = 1;
				nl = min(nl, seg[nid].fi), nr = max(nr, seg[nid].se);
				fa[nid] = idcnt;
			}
			seg[idcnt] = mp(nl, nr);
			ch(root, nl + 1, nr - 1, idcnt);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define maxn 300010
#define ll long long
#define db double
#define vi vector<int>
#define pb push_back
#define mod 998244353
#define pi pair<int, int>
#define fi first
#define se second
#define mp make_pair
ll ksm(ll a, ll b) {
   if (!b) return 1;
   ll ns = ksm(a, b >> 1);
   ns = ns * ns % mod;
   if (b & 1) ns = ns * a % mod;
   return ns;
}
// head
int t, tp[maxn], a[maxn], b[maxn];
int fa[maxn], vis[maxn];
pi seg[maxn];
int gfa(int a) {
	if (fa[a] == a) return a;
	return fa[a] = gfa(fa[a]);
}
struct ST {
	int l, r;
	ST *ch[2];
	vi tr;
}p[maxn << 1], *root;
int stcnt = 0;
void bdtree(ST *a, int l, int r) {
	a->l = l, a->r = r;
	if (l == r) return;
	int mid = (l + r) >> 1;
	a->ch[0] = &p[stcnt++], a->ch[1] = &p[stcnt++];
	bdtree(a->ch[0], l, mid), bdtree(a->ch[1], mid + 1, r);
}
void ch(ST *a, int l, int r, int id) {
	if (l > r) return ;
	if (a->l == l && a->r == r) {
		a->tr.pb(id);
		return ;
	}
	int mid = (a->l + a->r) >> 1;
	if (r <= mid) ch(a->ch[0], l, r, id);
	else if (l > mid) ch(a->ch[1], l, r, id);
	else ch(a->ch[0], l, mid, id),
		ch(a->ch[1], mid + 1, r, id);
}
vi res;
void q(ST *a, int pl) {
	res.insert(res.end(), a->tr.begin(), a->tr.end());
	a->tr.clear();
	if (a->l == a->r) return ;
	int mid = (a->l + a->r) >> 1;
	if (pl <= mid) q(a->ch[0], pl);
	else q(a->ch[1], pl);
}
pi re[maxn];
int id[maxn];
int idcnt = 0, ncnt = 0;
int main() {
	for (int i = 0; i < maxn; i++)
		fa[i] = i;
	int n;
	cin >> n;
	vi st;
	for (int i = 1; i <= n; i++)
		scanf("%d%d%d", &tp[i], &a[i], &b[i]),
		st.pb(a[i]), st.pb(b[i]);

	sort(st.begin(), st.end());
	for (int i = 1; i <= n; i++)
		if (tp[i] == 1)
			a[i] = lower_bound(st.begin(), st.end(), a[i]) - st.begin(),
			b[i] = lower_bound(st.begin(), st.end(), b[i]) - st.begin();
	root = &p[stcnt++];
	bdtree(root, 0, st.size());
	for (int i = 1; i <= n; i++) {
		if (tp[i] == 2) {
			int ans = 0;
			int ns = gfa(id[b[i]]);
			if (seg[ns].fi < re[a[i]].fi && seg[ns].se > re[a[i]].fi) ans = 1;
			if (seg[ns].fi < re[a[i]].se && seg[ns].se > re[a[i]].se) ans = 1;
			if (ans) printf("YES\n");
			else printf("NO\n");
		}
		else {
			re[++ncnt] = mp(a[i], b[i]);
			id[ncnt] = ++idcnt;
			seg[idcnt] = mp(a[i], b[i]);
			res.clear();
			q(root, a[i]),
			q(root, b[i]);
			res.pb(idcnt);
			++idcnt;
			int nl = 1e9, nr = -1e9;
			for (int i = 0; i < res.size(); i++) {
				int nid = res[i];
				if (vis[nid]) continue;
				vis[nid] = 1;
				nl = min(nl, seg[nid].fi), nr = max(nr, seg[nid].se);
				fa[nid] = idcnt;
			}
			seg[idcnt] = mp(nl, nr);
			ch(root, nl + 1, nr - 1, idcnt);
		}
	}
	return 0;
}


//https://codeforces.com/problemset/problem/319/E
#include <bits/stdc++.h>

using namespace std;

const int maxn = 100010*2;
const int maxw = 1e9;

vector<int> tmp;

int n, c;
int L[maxn], R[maxn], fa[maxn];
int qo[maxn], qx[maxn], qy[maxn];

vector<int> T[maxn<<2];
vector<int> vres;

int getroot(int x) {
	if (x == fa[x]) return x;
	return fa[x] = getroot(fa[x]);
}

void upd(int L, int R, int x, int l, int r, int rt) {
	if (L > R) return;
	if (L <= l && r <= R) {
		T[rt].push_back(x);
		return;
	}
	int m = (l + r) >> 1;
	if (L <= m) upd(L, R, x, l, m, rt<<1);
	if (R > m) upd(L, R, x, m+1, r, rt<<1|1);
}

void qry(int p, int l, int r, int rt) {
	vres.insert(vres.end(), T[rt].begin(), T[rt].end());
	T[rt].clear();
	if (l == r) return;
	int m = (l + r) >> 1;
	if (p <= m) qry(p, l, m, rt<<1);
	else qry(p, m+1, r, rt<<1|1);
}

// x 是根，把 y 加入 x
void Union(int x, int y) {
	int ry = getroot(y);
	fa[ry] = x;
	L[x] = min(L[x], L[ry]);
	R[x] = max(R[x], R[ry]);
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%d%d%d", &qo[i], &qx[i], &qy[i]);
		if (qo[i] == 1) {
			tmp.push_back(qx[i]), tmp.push_back(qy[i]);
		}
	}
	sort(tmp.begin(), tmp.end());
	for (int i = 1; i <= n; i++) {
		if (qo[i] == 1) {
			qx[i] = int (lower_bound(tmp.begin(), tmp.end(), qx[i]) - tmp.begin() + 1);
			qy[i] = int (lower_bound(tmp.begin(), tmp.end(), qy[i]) - tmp.begin() + 1);
			++ c;
			L[c] = qx[i], R[c] = qy[i];
			fa[c] = c;
		}
	}
	int _c = 0;
	for (int i = 1; i <= n; i++) {
		if (qo[i] == 1) {
			++ _c;
			vres.clear();
			int l = qx[i], r = qy[i];
			qry(l, 1, 2*n, 1), qry(r, 1, 2*n, 1);
			for (int i = 0; i < vres.size(); i++) Union(_c, vres[i]);
			upd(L[_c]+1, R[_c]-1, _c, 1, 2*n, 1);
		} else {
			int rx = getroot(qx[i]), ry = getroot(qy[i]);
			if (L[rx] >= L[ry] && R[rx] <= R[ry]) puts("YES");
			else puts("NO");
		}
	}
	return 0;
}


#include<bits/stdc++.h>

#define y1 dmytxdy
#define fi first
#define se second
#define mp make_pair

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef long double ld;
typedef vector<int> vi;

template <typename T> bool chkmin(T &x,T y){return x>y?x=y,1:0;}
template <typename T> bool chkmax(T &x,T y){return x<y?x=y,1:0;}

int readint(){
	int x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

struct node{
	vi vec;
}t[600000];

int n,m,cnt;
int opt[100005],x[100005],y[100005],p[200005],f[100005];
pii a[100005],b[100005];
bool vis[100005];

int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}

void change(int id,int l,int r,int ql,int qr,int x){
	if(l==ql&&r==qr) return (void)(t[id].vec.push_back(x));
	int mid=(l+r)/2;
	if(qr<=mid) change(id<<1,l,mid,ql,qr,x);
	else if(ql>mid) change(id<<1|1,mid+1,r,ql,qr,x);
	else change(id<<1,l,mid,ql,mid,x),change(id<<1|1,mid+1,r,mid+1,qr,x);
}

void query(int id,int l,int r,int x,vi &ret){
	if(l==r){
		for(auto r:t[id].vec) if(!vis[r]) ret.push_back(r);
		t[id].vec.clear();
		return;
	}
	int mid=(l+r)/2;
	for(auto r:t[id].vec) if(!vis[r]) ret.push_back(r);
	t[id].vec.clear();
	if(x<=mid) query(id<<1,l,mid,x,ret);
	else query(id<<1|1,mid+1,r,x,ret);
	return;
}

int main(){
	n=readint();
	for(int i=1;i<=n;i++){
		opt[i]=readint(); x[i]=readint(); y[i]=readint();
		if(opt[i]==1) p[++m]=x[i],p[++m]=y[i];
	}
	sort(p+1,p+m+1); m=unique(p+1,p+m+1)-p-1;
	for(int i=1;i<=n;i++) if(opt[i]==1) x[i]=lower_bound(p+1,p+m+1,x[i])-p,y[i]=lower_bound(p+1,p+m+1,y[i])-p;
	for(int i=1;i<=n;i++) f[i]=i;
	for(int i=1;i<=n;i++){
		if(opt[i]==1){
			int l=x[i]+1,r=y[i]-1;
			vi tmp(0),tmp1(0);
			query(1,1,m,x[i],tmp),query(1,1,m,y[i],tmp1);
			tmp.insert(tmp.end(),tmp1.begin(),tmp1.end());
			for(auto t:tmp) vis[t]=1,chkmin(l,a[t].fi),chkmax(r,a[t].se),f[t]=cnt+1;
			a[++cnt]=mp(l,r),b[cnt]=mp(x[i],y[i]);
			change(1,1,m,l,r,cnt);
		}
		else{
			int fx=getf(y[i]);
			if((a[fx].fi<=b[x[i]].fi&&b[x[i]].fi<=a[fx].se)||(a[fx].fi<=b[x[i]].se&&b[x[i]].se<=a[fx].se)) printf("YES\n");
			else printf("NO\n");
		}
	}
	return 0;
}


#include<bits/stdc++.h>

#define y1 dmytxdy
#define fi first
#define se second
#define mp make_pair

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef long double ld;
typedef vector<int> vi;

template <typename T> bool chkmin(T &x,T y){return x>y?x=y,1:0;}
template <typename T> bool chkmax(T &x,T y){return x<y?x=y,1:0;}

int readint(){
	int x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

struct node{
	vi vec;
}t[600000];

int n,m,cnt;
int opt[100005],x[100005],y[100005],p[200005],f[100005];
pii a[100005],b[100005];
bool vis[100005];

int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}

void change(int id,int l,int r,int ql,int qr,int x){
	if(l==ql&&r==qr) return (void)(t[id].vec.push_back(x));
	int mid=(l+r)/2;
	if(qr<=mid) change(id<<1,l,mid,ql,qr,x);
	else if(ql>mid) change(id<<1|1,mid+1,r,ql,qr,x);
	else change(id<<1,l,mid,ql,mid,x),change(id<<1|1,mid+1,r,mid+1,qr,x);
}

vi query(int id,int l,int r,int x){
	if(l==r){
		vi ret(0);
		for(auto r:t[id].vec) ret.push_back(r);
		return ret;
	}
	int mid=(l+r)/2;
	vi ret(0),tmp(0);
	for(auto r:t[id].vec) if(!vis[r]) ret.push_back(r);
	if(x<=mid) tmp=query(id<<1,l,mid,x);
	else tmp=query(id<<1|1,mid+1,r,x);
	ret.insert(ret.end(),tmp.begin(),tmp.end());
	return ret;
}

int main(){
	n=readint();
	for(int i=1;i<=n;i++){
		opt[i]=readint(); x[i]=readint(); y[i]=readint();
		if(opt[i]==1) p[++m]=x[i],p[++m]=y[i];
	}
	sort(p+1,p+m+1); m=unique(p+1,p+m+1)-p-1;
	for(int i=1;i<=n;i++) if(opt[i]==1) x[i]=lower_bound(p+1,p+m+1,x[i])-p,y[i]=lower_bound(p+1,p+m+1,y[i])-p;
	for(int i=1;i<=n;i++) f[i]=i;
	for(int i=1;i<=n;i++){
		if(opt[i]==1){
			int l=x[i]+1,r=y[i]-1;
			vi tmp=query(1,1,m,x[i]),tmp1=query(1,1,m,y[i]);
			tmp.insert(tmp.end(),tmp1.begin(),tmp1.end());
			for(auto t:tmp) vis[t]=1,chkmin(l,a[t].fi),chkmax(r,a[t].se),f[t]=cnt+1;
			a[++cnt]=mp(l,r),b[cnt]=mp(x[i],y[i]);
			change(1,1,m,l,r,cnt);
		}
		else{
			int fx=getf(y[i]);
			if((a[fx].fi<=b[x[i]].fi&&b[x[i]].fi<=a[fx].se)||(a[fx].fi<=b[x[i]].se&&b[x[i]].se<=a[fx].se)) printf("YES\n");
			else printf("NO\n");
		}
	}
	return 0;
}


#include<bits/stdc++.h>

#define y1 dmytxdy
#define fi first
#define se second
#define mp make_pair

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef long double ld;
typedef vector<int> vi;

template <typename T> bool chkmin(T &x,T y){return x>y?x=y,1:0;}
template <typename T> bool chkmax(T &x,T y){return x<y?x=y,1:0;}

int readint(){
	int x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

struct node{
	vi vec;
}t[600000];

int n,m,cnt;
int opt[100005],x[100005],y[100005],p[200005],f[100005];
pii a[100005],b[100005];
bool vis[100005];

int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}

void change(int id,int l,int r,int ql,int qr,int x){
	if(ql>qr) return;
	if(l==ql&&r==qr) return (void)(t[id].vec.push_back(x));
	int mid=(l+r)/2;
	if(qr<=mid) change(id<<1,l,mid,ql,qr,x);
	else if(ql>mid) change(id<<1|1,mid+1,r,ql,qr,x);
	else change(id<<1,l,mid,ql,mid,x),change(id<<1|1,mid+1,r,mid+1,qr,x);
}

void query(int id,int l,int r,int x,vi &ret){
	if(l==r){
		for(auto r:t[id].vec) if(!vis[r]) ret.push_back(r);
		t[id].vec.clear();
		return;
	}
	int mid=(l+r)/2;
	for(auto r:t[id].vec) if(!vis[r]) ret.push_back(r);
	t[id].vec.clear();
	if(x<=mid) query(id<<1,l,mid,x,ret);
	else query(id<<1|1,mid+1,r,x,ret);
	return;
}

int main(){
	n=readint();
	for(int i=1;i<=n;i++){
		opt[i]=readint(); x[i]=readint(); y[i]=readint();
		if(opt[i]==1) p[++m]=x[i],p[++m]=y[i];
	}
	sort(p+1,p+m+1); m=unique(p+1,p+m+1)-p-1;
	for(int i=1;i<=n;i++) if(opt[i]==1) x[i]=lower_bound(p+1,p+m+1,x[i])-p,y[i]=lower_bound(p+1,p+m+1,y[i])-p;
	for(int i=1;i<=n;i++) f[i]=i;
	for(int i=1;i<=n;i++){
		if(opt[i]==1){
			int l=x[i]+1,r=y[i]-1;
			vi tmp(0),tmp1(0);
			query(1,1,m,x[i],tmp),query(1,1,m,y[i],tmp1);
			tmp.insert(tmp.end(),tmp1.begin(),tmp1.end());
			for(auto t:tmp) vis[t]=1,chkmin(l,a[t].fi),chkmax(r,a[t].se),f[t]=cnt+1;
			a[++cnt]=mp(l,r),b[cnt]=mp(x[i],y[i]);
			change(1,1,m,l,r,cnt);
		}
		else{
			int fx=getf(y[i]);
			if((a[fx].fi<=b[x[i]].fi&&b[x[i]].fi<=a[fx].se)||(a[fx].fi<=b[x[i]].se&&b[x[i]].se<=a[fx].se)) printf("YES\n");
			else printf("NO\n");
		}
	}
	return 0;
}


#include<bits/stdc++.h>

#define y1 dmytxdy
#define fi first
#define se second
#define mp make_pair

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef long double ld;
typedef vector<int> vi;

template <typename T> bool chkmin(T &x,T y){return x>y?x=y,1:0;}
template <typename T> bool chkmax(T &x,T y){return x<y?x=y,1:0;}

int readint(){
	int x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

struct node{
	vi vec;
}t[600000];

int n,m,cnt;
int opt[100005],x[100005],y[100005],p[200005],f[100005];
pii a[100005],b[100005];
bool vis[100005];

int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}

void change(int id,int l,int r,int ql,int qr,int x){
	if(l==ql&&r==qr) return (void)(t[id].vec.push_back(x));
	int mid=(l+r)/2;
	if(qr<=mid) change(id<<1,l,mid,ql,qr,x);
	else if(ql>mid) change(id<<1|1,mid+1,r,ql,qr,x);
	else change(id<<1,l,mid,ql,mid,x),change(id<<1|1,mid+1,r,mid+1,qr,x);
}

vi query(int id,int l,int r,int x){
	if(l==r){
		vi ret(0);
		for(auto r:t[id].vec) if(!vis[r]) ret.push_back(r);
		t[id].vec.clear();
		return ret;
	}
	int mid=(l+r)/2;
	vi ret(0),tmp(0);
	for(auto r:t[id].vec) if(!vis[r]) ret.push_back(r);
	if(x<=mid) tmp=query(id<<1,l,mid,x);
	else tmp=query(id<<1|1,mid+1,r,x);
	ret.insert(ret.end(),tmp.begin(),tmp.end());
	t[id].vec.clear();
	return ret;
}

int main(){
	n=readint();
	for(int i=1;i<=n;i++){
		opt[i]=readint(); x[i]=readint(); y[i]=readint();
		if(opt[i]==1) p[++m]=x[i],p[++m]=y[i];
	}
	sort(p+1,p+m+1); m=unique(p+1,p+m+1)-p-1;
	for(int i=1;i<=n;i++) if(opt[i]==1) x[i]=lower_bound(p+1,p+m+1,x[i])-p,y[i]=lower_bound(p+1,p+m+1,y[i])-p;
	for(int i=1;i<=n;i++) f[i]=i;
	for(int i=1;i<=n;i++){
		if(opt[i]==1){
			int l=x[i]+1,r=y[i]-1;
			vi tmp=query(1,1,m,x[i]),tmp1=query(1,1,m,y[i]);
			tmp.insert(tmp.end(),tmp1.begin(),tmp1.end());
			for(auto t:tmp) vis[t]=1,chkmin(l,a[t].fi),chkmax(r,a[t].se),f[t]=cnt+1;
			a[++cnt]=mp(l,r),b[cnt]=mp(x[i],y[i]);
			change(1,1,m,l,r,cnt);
		}
		else{
			int fx=getf(y[i]);
			if((a[fx].fi<=b[x[i]].fi&&b[x[i]].fi<=a[fx].se)||(a[fx].fi<=b[x[i]].se&&b[x[i]].se<=a[fx].se)) printf("YES\n");
			else printf("NO\n");
		}
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 200010;
const int inf = (int) 1e9 + 9;

int pr[N];
int L[N], R[N];

int get(int x) {
  return (pr[x] == -1 ? x : (pr[x] = get(pr[x])));
}

bool unite(int x, int y) {
  x = get(x);
  y = get(y);
  if (x != y) {
    pr[x] = y;
    L[y] = min(L[y], L[x]);
    R[y] = max(R[y], R[x]);
    return true;
  }
  return false;
}

vector<int> t[4 * N];

void add(int v, int l, int r, int x, int tl, int tr) {
  if (r <= tl || tr <= l) {
    return;
  } else if (l <= tl && tr <= r) {
    t[v].push_back(x);
  } else {
    int tm = (tl + tr) / 2;
    add(2 * v + 1, l, r, x, tl, tm);
    add(2 * v + 2, l, r, x, tm, tr);
  }
}

void upd(int v, int x, int y, int tl, int tr) {
  while (!t[v].empty()) {
    int z = t[v].back();
    t[v].pop_back();
    unite(y, z);
  }
  if (tr - tl == 1) {
    return;
  }
  int tm = (tl + tr) / 2;
  if (x < tm) {
    upd(2 * v + 1, x, y, tl, tm);
  } else {
    upd(2 * v + 2, x, y, tm, tr);
  }
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> a(n);
  vector<int> b(n);
  vector<int> t(n);
  vector<int> vec;
  vec.push_back(-inf);
  memset(pr, -1, sizeof(pr));
  for (int i = 0; i < n; i++) {
    cin >> t[i] >> a[i] >> b[i];
    if (t[i] == 1) {
      vec.push_back(a[i]);
      vec.push_back(b[i]);
    } else {
      --a[i]; --b[i];
    }
  }
  sort(vec.begin(), vec.end());
  vec.resize(unique(vec.begin(), vec.end()) - vec.begin());
  vector<int> all;
  for (int i = 0; i < n; i++) {
    if (t[i] == 1) {
      all.push_back(i);
      L[i] = a[i] = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin();
      R[i] = b[i] = lower_bound(vec.begin(), vec.end(), b[i]) - vec.begin();
      upd(0, a[i], i, 0, N);
      upd(0, b[i], i, 0, N);
      add(0, L[get(i)] + 1, R[get(i)], i, 0, N);
    } else {
      int x = get(all[a[i]]);
      int y = get(all[b[i]]);
      cout << (L[y] <= L[x] && R[x] <= R[y] ? "YES" : "NO") << '\n';
    }
  }
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 200010;
const int inf = (int) 1e9 + 9;

int pr[N];
int L[N], R[N];

int get(int x) {
  return (pr[x] == -1 ? x : (pr[x] = get(pr[x])));
}

bool unite(int x, int y) {
  x = get(x);
  y = get(y);
  if (x != y) {
    pr[x] = y;
    L[y] = min(L[y], L[x]);
    R[y] = max(R[y], R[x]);
    return true;
  }
  return false;
}

vector<int> t[4 * N];

void add(int v, int l, int r, int x, int tl, int tr) {
  if (r <= tl || tr <= l) {
    return;
  } else if (l <= tl && tr <= r) {
    t[v].push_back(x);
  } else {
    int tm = (tl + tr) / 2;
    add(2 * v + 1, l, r, x, tl, tm);
    add(2 * v + 2, l, r, x, tm, tr);
  }
}

void upd(int v, int x, int y, int tl, int tr) {
  while (!t[v].empty()) {
    int z = t[v].back();
    t[v].pop_back();
    unite(y, z);
  }
  if (tr - tl == 1) {
    return;
  }
  int tm = (tl + tr) / 2;
  if (x < tm) {
    upd(2 * v + 1, x, y, tl, tm);
  } else {
    upd(2 * v + 2, x, y, tm, tr);
  }
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> a(n);
  vector<int> b(n);
  vector<int> t(n);
  vector<int> vec;
  memset(pr, -1, sizeof(pr));
  for (int i = 0; i < n; i++) {
    cin >> t[i] >> a[i] >> b[i];
    if (t[i] == 1) {
      vec.push_back(a[i]);
      vec.push_back(b[i]);
    } else {
      --a[i]; --b[i];
    }
  }
  sort(vec.begin(), vec.end());
  vec.resize(unique(vec.begin(), vec.end()) - vec.begin());
  vector<int> all;
  for (int i = 0; i < n; i++) {
    if (t[i] == 1) {
      all.push_back(i);
      L[i] = a[i] = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin();
      R[i] = b[i] = lower_bound(vec.begin(), vec.end(), b[i]) - vec.begin();
      upd(0, a[i], i, 0, N);
      upd(0, b[i], i, 0, N);
      add(0, L[get(i)] + 1, R[get(i)], i, 0, N);
    } else {
      int x = get(all[a[i]]);
      int y = get(all[b[i]]);
      cout << (L[y] <= L[x] && R[x] <= R[y] ? "YES" : "NO") << '\n';
    }
  }
  return 0;
}


#include<cctype>
#include<cstdio>
#include<vector>
const int N=100007;
int root,cnt,tot,ch[N*40][2];
struct node{int fa,l,r,size;}t[N];
std::vector<int>vec[N*40];
int read(){int x=0,c=getchar(),f=1;while(isspace(c))c=getchar();if(c=='-')f=-1,c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return f*x;}
int find(int x){return x==t[x].fa? x:t[x].fa=find(t[x].fa);}
void merge(int u,int v){if((u=find(u))^(v=find(v)))t[u].fa=v,t[v].l=std::min(t[v].l,t[u].l),t[v].r=std::max(t[v].r,t[u].r),t[v].size+=t[u].size;}
#define mid ((l+r)>>1)
void update(int&p,int l,int r,int L,int R,int x)
{
    if(l>R||L>r||L>R) return ;
    if(!p) p=++tot;
    if(L<=l&&r<=R) return vec[p].push_back(x);
    update(ch[p][0],l,mid,L,R,x),update(ch[p][1],mid+1,r,L,R,x);
}
void link(int p,int l,int r,int x,int u)
{
    for(auto v:vec[p]) merge(v,u);
    if(vec[p].size()>1) vec[p].resize(1);
    if(!p) return ;
    x<=mid? link(ch[p][0],l,mid,x,u):link(ch[p][1],mid+1,r,x,u);
}
#undef mid
void update()
{
    int l=read(),r=read();
    ++cnt,t[cnt]={cnt,l,r,1},update(root,-1e9,1e9,l+1,r-1,cnt),link(root,-1e9,1e9,l,cnt),link(root,-1e9,1e9,r,cnt);
}
void query(){int u=find(read()),v=find(read());puts(t[v].l<=t[u].l&&t[u].r<=t[v].r&&!(t[u].l==t[v].l&&t[u].r==t[v].r&&t[u].size==1)?"YES":"NO");}
int main(){for(int n=read();n;--n) read()==1? update():query();}


#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

struct query {
    int type, l, r;
};
const int MAXN = 100000;
query Q[MAXN];
int intervals[MAXN];
int L[MAXN], R[MAXN];

int UF[MAXN];
int find(int x) {
    if (UF[x] == x) {
        return x;
    } else {
        UF[x] = find(UF[x]);
        return UF[x];
    }
}
int join(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) {
        return x;
    } else {
        L[x] = L[y] = min(L[x], L[y]);
        R[x] = R[y] = max(R[x], R[y]);
        if (rand()&1) {
            UF[x] = y;
            return y;
        } else {
            UF[y] = x;
            return x;
        }
    }
}

struct Tournament {
    vector<set<int> > covers;
    int n, l, r;
    Tournament(int N) {
        for (n=1; n<N; n*=2) ;
        covers.assign(2*n, set<int>());
    }
    void put(int l, int r, int comp) {
        this->l = l;
        this->r = r;
        put(1, 0, n, comp);
    }
    void put(int x, int a, int b, int comp) {
        if (r<=a || b<=l) return;
        if (l<=a && b<=r) {
            covers[x].insert(comp);
        } else {
            put(2*x, a, (a+b)/2, comp);
            put(2*x+1, (a+b)/2, b, comp);
        }
    }

    int unite(int pos, int comp) {
        return unite(1, 0, n, pos, comp);
    }
    int unite(int node, int a, int b, int pos, int comp) {
        if (node>=2*n || pos<a || pos>=b) return comp;
        for (set<int>::const_iterator it=covers[node].begin(); it!=covers[node].end(); ++it) {
            comp = join(comp, *it);
        }
        covers[node].clear();
        comp = unite(2*node, a, (a+b)/2, pos, comp);
        return unite(2*node+1, (a+b)/2, b, pos, comp);
    }
};
int main() {
    int n;
    scanf("%d", &n);
    vector<int> pos;
    int ni = 0;
    for (int i=0; i<n; ++i) {
        int t, l, r;
        scanf("%d %d %d", &t, &l, &r);
        --l; --r;
        Q[i] = (query){t, l, r};
        if (t == 1) {
            pos.push_back(l);
            pos.push_back(r);
            intervals[ni] = i;
            UF[ni] = ni;
            ++ni;
        }
    }
    sort(pos.begin(), pos.end());
    pos.resize(unique(pos.begin(), pos.end()) - pos.begin());
    Tournament T(pos.size());
    int ncomps = 0;
    for (int i=0; i<n; ++i) {
        if (Q[i].type == 1) {
            int l = lower_bound(pos.begin(), pos.end(), Q[i].l) - pos.begin();
            int r = lower_bound(pos.begin(), pos.end(), Q[i].r) - pos.begin();
            L[ncomps] = l;
            R[ncomps] = r;
            assert(UF[ncomps] == ncomps);
            ++ncomps;
            int comp = T.unite(l, ncomps-1);
            comp = T.unite(r, comp);
            if (L[comp]+1 < R[comp]) {
                T.put(L[comp]+1, R[comp], comp);
            }
        } else {
            int a = find(Q[i].l);
            int b = find(Q[i].r);
            if (a==b || (L[b]<=L[a] && R[a]<=R[b])) {
                puts("YES");
            } else {
                puts("NO");
            }
        }
    }

	return 0;
}


#include <bits/stdc++.h>
typedef int ll;
typedef long double ld;
#define pb push_back
#define pii pair < int , int >
#define F first
#define S second
#define endl '\n'
//#define int long long
#define sync ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#define kill(x) return cout<<x<<'\n', 0;
using namespace std;
const int N=2e5+100;
ll par[N];
ll lf[N],rt[N];
ll getpar(ll v){
    if (par[v]==v) return v;
    return par[v]=getpar(par[v]);
}
set <int> seg[N*4];
void add(ll nod,ll l,ll r,ll L,ll R,ll val){
    if (l>=R || L>=r) return ;
    if (l>=L && r<=R){
        seg[nod].insert(val);
        return ;
    }
    ll mid=(r+l)/2;
    add(nod*2,l,mid,L,R,val);
    add(nod*2+1,mid,r,L,R,val);
}
void del(ll nod,ll l,ll r,ll L,ll R,ll val){
    if (l>=R || L>=r) return ;
    if (l>=L && r<=R){
        seg[nod].erase(val);
        return ;
    }
    ll mid=(r+l)/2;
    del(nod*2,l,mid,L,R,val);
    del(nod*2+1,mid,r,L,R,val);
}
void merg(ll x,ll y){
    x=getpar(x);
    y=getpar(y);
    del(1,1,N,lf[y]+1,rt[y],y);
    del(1,1,N,lf[x]+1,rt[x],x);
    par[x]=y;
    lf[y]=min(lf[y],lf[x]);
    rt[y]=max(rt[y],rt[x]);
    add(1,1,N,lf[y]+1,rt[y],y);
}
vector <pii> a;
void get(ll nod,ll l,ll r,ll id,ll x){

    for (auto u : seg[nod]){
        ll z=u;
        a.pb({x,z});
    }
    if (r-l==1) return ;
    ll mid=(r+l)/2;
    if (mid>id) get(nod*2,l,mid,id,x);
    else get(nod*2+1,mid,r,id,x);
}
map <int,int> mp;
vector <int> com;
pii W[N];
int32_t main(){
    ll n;
    cin >> n;
    vector <pair <int,pii> > q;
    ll cnt=0;
    for (int i=0;i<n;i++){
        ll t,l,r;
        cin >> t >> l >> r;
        q.pb({t,{l,r}});
        if (t==1){
            com.pb(l);
            com.pb(r);
        }
    }
    sort(com.begin(),com.end());
    com.resize(unique(com.begin(),com.end())-com.begin());
    for (int i=0;i<com.size();i++){
        mp[com[i]]=i+1;
    }
    for (int i=0;i<q.size();i++){
        if (q[i].F==1){
            cnt++;
            par[cnt]=cnt;
            q[i].S.F=mp[q[i].S.F];
            q[i].S.S=mp[q[i].S.S];
            ll l=q[i].S.F;
            ll r=q[i].S.S;
            W[cnt]={l,r};
            lf[cnt]=l;
            rt[cnt]=r;
            a.clear();
            get(1,1,N,l,cnt);
            get(1,1,N,r,cnt);
            add(1,1,N,lf[cnt]+1,rt[cnt],cnt);
            for (auto u : a){
                merg(u.F,u.S);
            }
        }
        else{
            ll u=q[i].S.F,v=q[i].S.S;
            u=getpar(u);
            v=getpar(v);
            if (u==v || (lf[v]<W[u].F && rt[v]>W[u].S) || (lf[v]<W[u].S && rt[v]>W[u].S)){
                cout << "YES" << endl;
            }
            else{
                cout << "NO" << endl;
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int nax = 1e5;
int par[nax];
int find(int p) {
  return p == par[p] ? p : p = find(par[p]);
}

struct Interval {
  int id;
  int l, r;
  map<int, Interval*> child;
  void recMerge(int p) {
    auto it = child.lower_bound(p);
    if (it == child.begin()) return;
    --it;
    Interval*o = it->second;
    if (o->l < p && o->r > p) {
      o->recMerge(p);
      l = min(l, o->l);
      r = max(r, o->r);
      if (o->child.size() > child.size()) {
	swap(o->child, child);
      }
      for (auto&c : o->child) {
	child.insert(c);
      }
      par[o->id] = id;
      o->child.clear();
      delete o;
    }
  }
};

Interval*ipos[nax];

int main() {
  ios::sync_with_stdio(0); cin.tie(0);
  int q;
  cin >> q;
  for (int i = 0; i < q; i++)
    par[i] = i;
  map<int, Interval*> roots;
  int added = 0;
  while (q--) {
    int type;
    cin >> type;
    if (type == 1) {
      int l, r;
      cin >> l >> r;
      Interval*toadd = new Interval({added,l,r});
      ipos[added++] = toadd;

      vector<int> to_erase;
      auto it = roots.lower_bound(r);
      while (it != roots.begin() && (--it)->second->r > l) {
	to_erase.push_back(it->second->l);
	toadd->child[it->first] = it->second;
      }
      for (int i : to_erase)
	roots.erase(i);
      toadd->recMerge(l);
      toadd->recMerge(r);
      roots[toadd->l] = toadd;
    } else {
      assert(type == 2);
      int a, b;
      cin >> a >> b;
      a--, b--;
      a = find(a);
      b = find(b);
      Interval*ia = ipos[a], *ib = ipos[b];
      cout << (a == b || ib->l <= ia->l && ib->r >= ia->r ? "YES" : "NO") << '\n';
    }
  }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int nax = 1e5;
int par[nax];
int find(int p) {
  return p == par[p] ? p : par[p] = find(par[p]);
}

struct Interval {
  int id;
  int l, r;
  map<int, Interval*> child;
  void recMerge(int p) {
    auto it = child.lower_bound(p);
    if (it == child.begin()) return;
    --it;
    Interval*o = it->second;
    if (o->l < p && o->r > p) {
      child.erase(o->l);
      o->recMerge(p);
      l = min(l, o->l);
      r = max(r, o->r);
      if (o->child.size() > child.size()) {
	swap(o->child, child);
      }
      for (auto&c : o->child) {
	child.insert(c);
      }
      par[o->id] = id;
      o->child.clear();
      delete o;
    }
  }
};

Interval*ipos[nax];

int main() {
  ios::sync_with_stdio(0); cin.tie(0);
  int q;
  cin >> q;
  for (int i = 0; i < q; i++)
    par[i] = i;
  map<int, Interval*> roots;
  int added = 0;
  while (q--) {
    int type;
    cin >> type;
    if (type == 1) {
      int l, r;
      cin >> l >> r;
      Interval*toadd = new Interval({added,l,r});
      ipos[added++] = toadd;

      vector<int> to_erase;
      auto it = roots.lower_bound(r);
      while (it != roots.begin() && (--it)->second->r > l) {
	to_erase.push_back(it->second->l);
	toadd->child[it->first] = it->second;
      }
      for (int i : to_erase)
	roots.erase(i);
      toadd->recMerge(l);
      toadd->recMerge(r);
      roots[toadd->l] = toadd;
    } else {
      assert(type == 2);
      int a, b;
      cin >> a >> b;
      a--, b--;
      a = find(a);
      b = find(b);
      Interval*ia = ipos[a], *ib = ipos[b];
      cout << (a == b || ib->l <= ia->l && ib->r >= ia->r ? "YES" : "NO") << '\n';
    }
  }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int nax = 1e5;
int par[nax];
int find(int p) {
  return p == par[p] ? p : p = find(par[p]);
}

struct Interval {
  int id;
  int l, r;
  map<int, Interval*> child;
  void recMerge(int p) {
    auto it = child.lower_bound(p);
    if (it == child.begin()) return;
    --it;
    Interval*o = it->second;
    if (o->l < p && o->r > p) {
      child.erase(o->l);
      o->recMerge(p);
      l = min(l, o->l);
      r = max(r, o->r);
      if (o->child.size() > child.size()) {
	swap(o->child, child);
      }
      for (auto&c : o->child) {
	child.insert(c);
      }
      par[o->id] = id;
      o->child.clear();
      delete o;
    }
  }
};

Interval*ipos[nax];

int main() {
  ios::sync_with_stdio(0); cin.tie(0);
  int q;
  cin >> q;
  for (int i = 0; i < q; i++)
    par[i] = i;
  map<int, Interval*> roots;
  int added = 0;
  while (q--) {
    int type;
    cin >> type;
    if (type == 1) {
      int l, r;
      cin >> l >> r;
      Interval*toadd = new Interval({added,l,r});
      ipos[added++] = toadd;

      vector<int> to_erase;
      auto it = roots.lower_bound(r);
      while (it != roots.begin() && (--it)->second->r > l) {
	to_erase.push_back(it->second->l);
	toadd->child[it->first] = it->second;
      }
      for (int i : to_erase)
	roots.erase(i);
      toadd->recMerge(l);
      toadd->recMerge(r);
      roots[toadd->l] = toadd;
    } else {
      assert(type == 2);
      int a, b;
      cin >> a >> b;
      a--, b--;
      a = find(a);
      b = find(b);
      Interval*ia = ipos[a], *ib = ipos[b];
      cout << (a == b || ib->l <= ia->l && ib->r >= ia->r ? "YES" : "NO") << '\n';
    }
  }
}


#include<bits/stdc++.h>
using namespace std;

typedef long long lint;
typedef long double louble;

template<typename T1,typename T2> inline T1 max(T1 a,T2 b){return a<b?b:a;}
template<typename T1,typename T2> inline T1 min(T1 a,T2 b){return a<b?a:b;}

const char lf = '\n';

namespace ae86
{
	const int bufl = 1 << 15;

	char buf[bufl],*s=buf,*t=buf;

	inline int fetch()
	{
		if(s==t){t=(s=buf)+fread(buf,1,bufl,stdin);if(s==t)return EOF;}
		return *s++;
	}

	inline int ty()
	{
		int a=0;int b=1,c=fetch();
		while(!isdigit(c))b^=c=='-',c=fetch();
		while(isdigit(c))a=a*10+c-48,c=fetch();
		return b?a:-a;
	}
}
using ae86::ty;

const int _ = 100007 , inf = 1e9;

int bfa[_]={0},bsz[_]={0},bl[_]={0},br[_]={0};

int findbfa(int x){return x==bfa[x]?x:bfa[x]=findbfa(bfa[x]);}

void linka(int a,int b)
{
	a=findbfa(a),b=findbfa(b);
	if(a==b)return;
	bfa[a]=b,bsz[b]+=bsz[a];
	bl[b]=min(bl[b],bl[a]),br[b]=max(br[b],br[a]);
}

struct jt
{
#define mid ((0ll+l+r)>>1)

	static const int _t = _ * 99;

	int lc[_t],rc[_t],tcnt;
	vector<int> hav[_t];

	void push(int &x,int l,int r,int tl,int tr,int d)
	{
		if(l>r || tl>tr)return;
		if(!x)x=++tcnt;
		if(tl<=l && r<=tr){hav[x].emplace_back(d);return;}
		if(tl<=mid)push(lc[x],l,mid,tl,tr,d);
		if(tr>mid)push(rc[x],mid+1,r,tl,tr,d);
	}

	void finder(int x,int l,int r,int tar,vector<int> &ans)
	{
		if(!x)return;
		ans.insert(ans.end(),hav[x].begin(),hav[x].end()),hav[x].clear();
		if(l==r)return;
		if(tar<=mid)finder(lc[x],l,mid,tar,ans);
		else finder(rc[x],mid+1,r,tar,ans);
	}

	jt()
	{
		memset(lc,0,sizeof(lc));
		memset(rc,0,sizeof(rc));
		tcnt=0;
	}

#undef mid
}t;
int rt=0;

int n=0,qn;

int main()
{
	ios::sync_with_stdio(0),cout.tie(nullptr);

	qn=ty();
	for(int qq=1;qq<=qn;qq++)
	{
		int op=ty(),a=ty(),b=ty();
		if(op==1)
		{
			a+=inf,b+=inf-1;
			n++,bfa[n]=n,bsz[n]=1,bl[n]=a,br[n]=b;
			vector<int> cxk;
			t.finder(rt,0,inf+inf,a,cxk),t.finder(rt,0,inf+inf,b+1,cxk);
			for(auto i:cxk)linka(i,n);
			t.push(rt,0,inf+inf,bl[n]+1,br[n],n);
		}
		if(op==2)
		{
			a=findbfa(a),b=findbfa(b);
			if(a==b)cout<<"YES"<<lf;
			else if(bl[a]==bl[b] && br[a]==br[b])cout<<(bsz[a]==1?"NO":"YES")<<lf;
			else if(bl[b]<=bl[a] && br[a]<=br[b])cout<<"YES"<<lf;
			else cout<<"NO"<<lf;
		}
	}

	return 0;
}


/* be name khoda */

// #define long_enable
#include <iostream>
#include <algorithm>
#include <cstring>
#include <numeric>
#include <vector>
#include <fstream>
#include <set>
#include <queue>
using namespace std;

#ifdef long_enable
typedef long long int ll;
#else
typedef int ll;
#endif

typedef pair<ll, ll> pii;
typedef pair<pii, ll> ppi;
typedef pair<ll, pii> pip;
typedef vector<ll> vi;
typedef vector<pii> vpii;

#define forifrom(i, s, n) for (ll i = s; i < n; ++i)
#define forirto(i, n, e) for (ll i = (n) - 1; i >= e; --i)
#define fori(i, n) forifrom (i, 0, n)
#define forir(i, n) forirto (i, n, 0)

#define F first
#define S second
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(), (x).end()
#define smin(a, b) a = min(a, (b))
#define smax(a, b) a = max(a, (b))

#define debug(x) cout << #x << " -> " << (x) << endl
#define debug2(x, y) cout << #x << ' ' << #y << " -> " << (x) << ' ' << (y) << endl
#define debug3(x, y, z) cout << #x << ' ' << #y << ' ' << #z << " -> " << (x) << ' ' << (y) << ' ' << (z) << endl
#define debug4(x, y, z, t) cout << #x << ' ' << #y << ' ' << #z << ' ' << #t << " -> " << (x) << ' ' << (y) << ' ' << (z) << ' ' << (t) << endl
#define debuga(x, n) cout << #x << " -> "; fori (i1_da, n) { cout << (x)[i1_da] << ' '; } cout << endl
#define debugaa(x, n, m) cout << #x << " ->\n"; fori (i1_daa, n) { fori (i2_daa, m) { cout << (x)[i1_daa][i2_daa] << ' '; } cout << '\n'; } cout << endl

const ll MOD = 1000000007;
const ll INF = 2000000000;
const long long BIG = 1446803456761533460LL;

#define XL (x << 1)
#define XR (XL | 1)
#define MD ((l + r) >> 1)
#define Add(a, b) a = ((a) + (b)) % MOD
#define Mul(a, b) a = (1LL * (a) * (b)) % MOD

// -----------------------------------------------------------------------

const ll maxn = 200010;

ll n, m, comp[maxn], par[maxn];
array<ll, 3> qs[maxn];
pii lr[maxn];

ppi seg[maxn * 2]; // {{r, id}, l}
priority_queue<pii> pq[maxn];

void update(ll p, pii v) {
    seg[p + m] = {v, p};
    for (p = (p + m) >> 1; p; p >>= 1) seg[p] = max(seg[p << 1], seg[p << 1 ^ 1]);
}

void add(ll l, ll r, ll id) {
    pq[l].emplace(r, id);
    if (pq[l].top() != seg[l + m].F) update(l, pq[l].top());
}

void pop(ll l) {
    pq[l].pop();
    pii v = pq[l].empty() ? make_pair(-1, -1) : pq[l].top();
    if (v != seg[l + m].F) update(l, v);
}

ppi get(ll l, ll r) {
    ppi mx = {{-1, -1}, -1};
    for (l += m, r += m; l < r; l >>= 1, r >>= 1) {
        if (l & 1) smax(mx, seg[l]), ++l;
        if (r & 1) --r, smax(mx, seg[r]);
    }
    return mx;
}

ll getid(ll x) {
    return lower_bound(comp, comp + m, x) - comp;
}

ll root(ll x) {
    return par[x] == x ? x : par[x] = root(par[x]);
}

ll isect(ll l, ll r) {
    ppi a = get(0, l);
    if (a.F.F > l) {
        pop(a.S);
        return a.F.S;
    }
    ppi b = get(l + 1, r);
    if (b.F.F > r) {
        pop(b.S);
        return b.F.S;
    }
    return -1;
}

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

    cin >> n;
    fori (i, n) {
        ll t; cin >> t;
        if (t == 1) {
            ll l, r; cin >> l >> r;
            comp[m++] = l, comp[m++] = r;
            qs[i] = {t, l, r};
        } else {
            ll a, b; cin >> a >> b; --a, --b;
            qs[i] = {t, a, b};
        }
    }
    comp[m++] = -INF;
    sort(comp, comp + m);
    m = unique(comp, comp + m) - comp;

    iota(par, par + n, 0);

    ll in = 0;
    fori (i, n) {
        auto [t, a, b] = qs[i];
        if (t == 1) {
            ll l = getid(a), r = getid(b);
            lr[in] = {l, r};
            ll x;
            while ((x = isect(l, r)) != -1) {
                x = root(x);
                smin(lr[in].F, lr[x].F);
                smax(lr[in].S, lr[x].S);
                par[x] = in;
            }
            add(lr[in].F, lr[in].S, in);
            ++in;
        } else {
            ll ra = root(a), rb = root(b);
            if (ra == rb || lr[rb].F < lr[ra].F && lr[ra].S < lr[rb].S) cout << "YES\n";
            else cout << "NO\n";
        }
    }

}


/* be name khoda */

// #define long_enable
#include <iostream>
#include <algorithm>
#include <cstring>
#include <numeric>
#include <vector>
#include <fstream>
#include <array>
#include <queue>
using namespace std;

#ifdef long_enable
typedef long long int ll;
#else
typedef int ll;
#endif

typedef pair<ll, ll> pii;
typedef pair<pii, ll> ppi;
typedef pair<ll, pii> pip;
typedef vector<ll> vi;
typedef vector<pii> vpii;

#define forifrom(i, s, n) for (ll i = s; i < n; ++i)
#define forirto(i, n, e) for (ll i = (n) - 1; i >= e; --i)
#define fori(i, n) forifrom (i, 0, n)
#define forir(i, n) forirto (i, n, 0)

#define F first
#define S second
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(), (x).end()
#define smin(a, b) a = min(a, (b))
#define smax(a, b) a = max(a, (b))

#define debug(x) cout << #x << " -> " << (x) << endl
#define debug2(x, y) cout << #x << ' ' << #y << " -> " << (x) << ' ' << (y) << endl
#define debug3(x, y, z) cout << #x << ' ' << #y << ' ' << #z << " -> " << (x) << ' ' << (y) << ' ' << (z) << endl
#define debug4(x, y, z, t) cout << #x << ' ' << #y << ' ' << #z << ' ' << #t << " -> " << (x) << ' ' << (y) << ' ' << (z) << ' ' << (t) << endl
#define debuga(x, n) cout << #x << " -> "; fori (i1_da, n) { cout << (x)[i1_da] << ' '; } cout << endl
#define debugaa(x, n, m) cout << #x << " ->\n"; fori (i1_daa, n) { fori (i2_daa, m) { cout << (x)[i1_daa][i2_daa] << ' '; } cout << '\n'; } cout << endl

const ll MOD = 1000000007;
const ll INF = 2000000000;
const long long BIG = 1446803456761533460LL;

#define XL (x << 1)
#define XR (XL | 1)
#define MD ((l + r) >> 1)
#define Add(a, b) a = ((a) + (b)) % MOD
#define Mul(a, b) a = (1LL * (a) * (b)) % MOD

// -----------------------------------------------------------------------

const ll maxn = 200010;

ll n, m, comp[maxn], par[maxn];
array<ll, 3> qs[maxn];
pii lr[maxn];

ppi seg[maxn * 2]; // {{r, id}, l}
priority_queue<pii> pq[maxn];

void update(ll p, pii v) {
    seg[p + m] = {v, p};
    for (p = (p + m) >> 1; p; p >>= 1) seg[p] = max(seg[p << 1], seg[p << 1 ^ 1]);
}

void add(ll l, ll r, ll id) {
    pq[l].emplace(r, id);
    if (pq[l].top() != seg[l + m].F) update(l, pq[l].top());
}

void pop(ll l) {
    pq[l].pop();
    pii v = pq[l].empty() ? make_pair(-1, -1) : pq[l].top();
    if (v != seg[l + m].F) update(l, v);
}

ppi get(ll l, ll r) {
    ppi mx = {{-1, -1}, -1};
    for (l += m, r += m; l < r; l >>= 1, r >>= 1) {
        if (l & 1) smax(mx, seg[l]), ++l;
        if (r & 1) --r, smax(mx, seg[r]);
    }
    return mx;
}

ll getid(ll x) {
    return lower_bound(comp, comp + m, x) - comp;
}

ll root(ll x) {
    return par[x] == x ? x : par[x] = root(par[x]);
}

ll isect(ll l, ll r) {
    ppi a = get(0, l);
    if (a.F.F > l) {
        pop(a.S);
        return a.F.S;
    }
    ppi b = get(l + 1, r);
    if (b.F.F > r) {
        pop(b.S);
        return b.F.S;
    }
    return -1;
}

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

    cin >> n;
    fori (i, n) {
        ll t; cin >> t;
        if (t == 1) {
            ll l, r; cin >> l >> r;
            comp[m++] = l, comp[m++] = r;
            qs[i] = {t, l, r};
        } else {
            ll a, b; cin >> a >> b; --a, --b;
            qs[i] = {t, a, b};
        }
    }
    comp[m++] = -INF;
    sort(comp, comp + m);
    m = unique(comp, comp + m) - comp;

    iota(par, par + n, 0);

    ll in = 0;
    fori (i, n) {
        auto [t, a, b] = qs[i];
        if (t == 1) {
            ll l = getid(a), r = getid(b);
            lr[in] = {l, r};
            ll x;
            while ((x = isect(l, r)) != -1) {
                x = root(x);
                smin(lr[in].F, lr[x].F);
                smax(lr[in].S, lr[x].S);
                par[x] = in;
            }
            add(lr[in].F, lr[in].S, in);
            ++in;
        } else {
            ll ra = root(a), rb = root(b);
            if (ra == rb || lr[rb].F < lr[ra].F && lr[ra].S < lr[rb].S) cout << "YES\n";
            else cout << "NO\n";
        }
    }

}