#include <bits/stdc++.h>
using namespace std;
int read() {
  char ch = getchar();
  int x = 0, flag = 1;
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') flag *= -1;
  for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
  return x * flag;
}
void write(int x) {
  if (x < 0) putchar('-'), x = -x;
  if (x >= 10) write(x / 10);
  putchar(x % 10 + 48);
}
const int Maxn = 400009;
struct quer {
  int opt, u, v;
};
struct interval {
  int l, r;
};
int n, s[Maxn][3], cnt1, tmp, tpd[Maxn * 2], d, shot[Maxn];
interval a[Maxn];
quer b[Maxn];
void init() {
  n = read();
  for (int i = (1), i_end_ = (n); i <= i_end_; ++i) {
    int opt = read(), l = read(), r = read();
    if (opt == 1) a[++cnt1] = (interval){l, r}, shot[i] = cnt1;
    b[i] = (quer){opt, l, r};
  }
  for (int i = (1), i_end_ = (cnt1); i <= i_end_; ++i) {
    tpd[++tmp] = a[i].l - 1, tpd[++tmp] = a[i].l;
    tpd[++tmp] = a[i].l + 1, tpd[++tmp] = a[i].r - 1;
    tpd[++tmp] = a[i].r, tpd[++tmp] = a[i].r + 1;
  }
  sort(tpd + 1, tpd + tmp + 1);
  d = unique(tpd + 1, tpd + tmp + 1) - tpd - 1;
  for (int i = (1), i_end_ = (cnt1); i <= i_end_; ++i) {
    a[i].l = lower_bound(tpd + 1, tpd + d + 1, a[i].l) - tpd,
    a[i].r = lower_bound(tpd + 1, tpd + d + 1, a[i].r) - tpd;
  }
  for (int i = (1), i_end_ = (n); i <= i_end_; ++i)
    if (b[i].opt == 1) b[i].u = a[shot[i]].l, b[i].v = a[shot[i]].r;
}
int L[Maxn], R[Maxn], amt, fa[Maxn];
int find(int u) { return fa[u] ^ u ? fa[u] = find(fa[u]) : u; }
namespace SGMTtree {
vector<int> tree[Maxn << 2];
void combine(int rt, int l, int r, int pos, int val) {
  if (!tree[rt].empty()) {
    for (int i = (0), i_end_ = (tree[rt].size() - 1); i <= i_end_; ++i) {
      int u = find(tree[rt][i]);
      L[val] = min(L[val], L[u]), R[val] = max(R[val], R[u]);
      fa[u] = val;
    }
    tree[rt].clear(), tree[rt].push_back(val);
  }
  if (l == r) return;
  int mid = (l + r) >> 1;
  (pos <= mid) ? combine(rt << 1, l, mid, pos, val)
               : combine(rt << 1 | 1, mid + 1, r, pos, val);
}
void update(int rt, int l, int r, int P, int Q, int val) {
  if (P > Q) return;
  if (P <= l && r <= Q) {
    tree[rt].push_back(val);
    return;
  }
  int mid = (l + r) >> 1;
  if (Q <= mid)
    update(rt << 1, l, mid, P, Q, val);
  else if (P >= mid + 1)
    update(rt << 1 | 1, mid + 1, r, P, Q, val);
  else
    update(rt << 1, l, mid, P, Q, val),
        update(rt << 1 | 1, mid + 1, r, P, Q, val);
}
};  // namespace SGMTtree
void solve() {
  for (int i = (1), i_end_ = (n); i <= i_end_; ++i) {
    if (b[i].opt == 1) {
      ++amt, L[amt] = b[i].u;
      R[amt] = b[i].v;
      fa[amt] = amt;
      SGMTtree ::combine(1, 1, d, L[amt], amt),
          SGMTtree ::combine(1, 1, d, R[amt], amt);
      SGMTtree ::combine(1, 1, d, b[i].u, amt),
          SGMTtree ::combine(1, 1, d, b[i].v, amt);
      SGMTtree ::update(1, 1, d, L[amt] + 1, R[amt] - 1, amt);
    } else {
      int p = find(b[i].u), q = find(b[i].v);
      if (p == q) {
        puts("YES");
        continue;
      }
      if ((L[q] < a[b[i].u].l && a[b[i].u].l < R[q]) ||
          (L[q] < a[b[i].u].r && a[b[i].u].r < R[q])) {
        puts("YES");
        continue;
      }
      puts("NO");
    }
  }
}
int main() {
  init();
  solve();
  return 0;
}
