#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
enum Color { RED, BLACK };
template <typename T>
class RBNode {
 public:
  T key;
  RBNode *left, *right, *p;
  Color color;
  RBNode(const T& val)
      : key(val), left(nullptr), right(nullptr), p(nullptr), color(BLACK) {}
  friend ostream& operator<<(ostream& os, const RBNode& n) {
    os << n.key;
    return os;
  }
};
template <typename T>
class RBTree {
 public:
  RBNode<T>* root;

 public:
  RBTree() : root(nullptr) {}
  void print() const {
    if (!root) return;
    RBNode<T>* node = minimumNode();
    RBNode<T>* maxNode = maximumNode();
    cout << endl;
    while (node != maxNode) {
      cout << (*node) << " -> ";
      node = successor(node);
    }
    cout << (*node) << endl;
  }
  RBNode<T>* search(const T& val) const {
    if (!root) return nullptr;
    return iterativeSearch(root, val);
  }
  RBNode<T>* searchGreaterElement(const T& val) const {
    RBNode<T>* node = search(val);
    if (node->key < val) return successor(node);
    return node;
  }
  RBNode<T>* successor(RBNode<T>* x) const {
    if (!x) return nullptr;
    if (x->right) return minimumNode(x->right);
    RBNode<T>* y = x->p;
    while (y && x == y->right) {
      x = y;
      y = y->p;
    }
    return y;
  }
  RBNode<T>* predeccesor(RBNode<T>* x) const {
    if (!x) return nullptr;
    if (x->left) return maximumNode(x->left);
    RBNode<T>* y = x->p;
    while (y && x == y->left) {
      x = y;
      y = y->p;
    }
    return y;
  }
  void insert(RBNode<T>* z) {
    RBNode<T>* y = nullptr;
    RBNode<T>* x = root;
    while (x) {
      y = x;
      if (z->key < x->key)
        x = x->left;
      else
        x = x->right;
    }
    z->p = y;
    if (!y)
      root = z;
    else if (z->key < y->key)
      y->left = z;
    else
      y->right = z;
    z->left = nullptr;
    z->right = nullptr;
    setColor(z, RED);
    insertFixup(z);
  }
  RBNode<T>* erase(RBNode<T>* z) {
    RBNode<T>*x, *y;
    if (!(z->left) || !(z->right))
      y = z;
    else
      y = successor(z);
    if (y->left)
      x = y->left;
    else
      x = y->right;
    setParent(x, y->p);
    if (!(y->p))
      root = x;
    else if (y == y->p->left)
      y->p->left = x;
    else
      y->p->right = x;
    if (y != z) z->key = y->key;
    if (getColor(y) == BLACK && x) eraseFixup(x);
    return y;
  }
  RBNode<T>* minimumNode() const { return minimumNode(root); }
  RBNode<T>* maximumNode() const { return maximumNode(root); }

 private:
  inline Color getColor(RBNode<T>* x) const {
    if (!x) return BLACK;
    return x->color;
  }
  inline void setColor(RBNode<T>* x, Color color) const {
    if (x) x->color = color;
  }
  inline void setParent(RBNode<T>* x, RBNode<T>* p) const {
    if (x) x->p = p;
  }
  RBNode<T>* iterativeSearch(RBNode<T>* x, const T& val) const {
    while ((x->left || x->right) && val != x->key) {
      if (val < x->key) {
        if (!(x->left)) return x;
        x = x->left;
      } else {
        if (!(x->right)) return x;
        x = x->right;
      }
    }
    return x;
  }
  RBNode<T>* minimumNode(RBNode<T>* x) const {
    while (x->left) x = x->left;
    return x;
  }
  RBNode<T>* maximumNode(RBNode<T>* x) const {
    while (x->right) x = x->right;
    return x;
  }
  void leftRotate(RBNode<T>* x) {
    RBNode<T>* y = x->right;
    x->right = y->left;
    setParent(y->left, x);
    setParent(y, x->p);
    if (!(x->p))
      root = y;
    else if (x == x->p->left)
      x->p->left = y;
    else
      x->p->right = y;
    y->left = x;
    setParent(x, y);
  }
  void rightRotate(RBNode<T>* x) {
    RBNode<T>* y = x->left;
    x->left = y->right;
    setParent(y->right, x);
    setParent(y, x->p);
    if (!(x->p))
      root = y;
    else if (x == x->p->right)
      x->p->right = y;
    else
      x->p->left = y;
    y->right = x;
    setParent(x, y);
  }
  void insertFixup(RBNode<T>* z) {
    RBNode<T>* y;
    while (getColor(z->p) == RED) {
      if (z->p == z->p->p->left) {
        y = z->p->p->right;
        if (getColor(y) == RED) {
          setColor(z->p, BLACK);
          setColor(y, BLACK);
          setColor(z->p->p, RED);
          z = z->p->p;
        } else {
          if (z == z->p->right) {
            z = z->p;
            leftRotate(z);
          }
          setColor(z->p, BLACK);
          setColor(z->p->p, RED);
          rightRotate(z->p->p);
        }
      } else {
        y = z->p->p->left;
        if (getColor(y) == RED) {
          setColor(z->p, BLACK);
          setColor(y, BLACK);
          setColor(z->p->p, RED);
          z = z->p->p;
        } else {
          if (z == z->p->left) {
            z = z->p;
            rightRotate(z);
          }
          setColor(z->p, BLACK);
          setColor(z->p->p, RED);
          leftRotate(z->p->p);
        }
      }
    }
    setColor(root, BLACK);
  }
  void eraseFixup(RBNode<T>* x) {
    while (x != root && getColor(x) == BLACK) {
      if (x == x->p->left) {
        RBNode<T>* w = x->p->right;
        if (getColor(w) == RED) {
          setColor(w, BLACK);
          setColor(x->p, RED);
          leftRotate(x->p);
          w = x->p->right;
        }
        if (!w) break;
        if (getColor(w->left) == BLACK && getColor(w->right) == BLACK) {
          setColor(w, RED);
          x = x->p;
        } else {
          if (getColor(w->right) == BLACK) {
            setColor(w->left, BLACK);
            setColor(w, RED);
            rightRotate(w);
            w = x->p->right;
          }
          setColor(w, x->p->color);
          setColor(x->p, BLACK);
          setColor(w->right, BLACK);
          leftRotate(x->p);
          x = root;
        }
      } else {
        RBNode<T>* w = x->p->left;
        if (getColor(w) == RED) {
          setColor(w, BLACK);
          setColor(x->p, RED);
          rightRotate(x->p);
          w = x->p->left;
        }
        if (!w) break;
        if (getColor(w->right) == BLACK && getColor(w->left) == BLACK) {
          setColor(w, RED);
          x = x->p;
        } else {
          if (getColor(w->left) == BLACK) {
            setColor(w->right, BLACK);
            setColor(w, RED);
            leftRotate(w);
            w = x->p->left;
          }
          setColor(w, x->p->color);
          setColor(x->p, BLACK);
          setColor(w->left, BLACK);
          rightRotate(x->p);
          x = root;
        }
      }
    }
    setColor(x, BLACK);
  }
};
class Point;
int64 area2(const Point& p, const Point& q, const Point& s);
int toLeft(const Point& p, const Point& q, const Point& s);
class Point {
 public:
  int64 x, y;
  Point(int64 x_ = 0, int64 y_ = 0) : x(x_), y(y_) {}
  bool operator<(const Point& p) const {
    return x < p.x || (x == p.x && y < p.y);
  }
  bool operator>(const Point& p) const {
    return x > p.x || (x == p.x && y > p.y);
  }
  bool operator!=(const Point& p) const { return x != p.x || y != p.y; }
  friend ostream& operator<<(ostream& os, const Point& p) {
    os << "(" << p.x << ", " << p.y << ")";
    return os;
  }
};
int64 area2(const Point& p, const Point& q, const Point& s) {
  return p.x * q.y - p.y * q.x + q.x * s.y - q.y * s.x + s.x * p.y - s.y * p.x;
}
int toLeft(const Point& p, const Point& q, const Point& s) {
  int64 area = area2(p, q, s);
  if (area > 0)
    return 1;
  else if (area == 0)
    return 0;
  else
    return -1;
}
class ConvexHull {
 private:
  RBTree<Point> t;
  int idx;

 public:
  ConvexHull() : idx(0) {}
  void print() { t.print(); }
  void insert(const Point& p) {
    if (idx < 2) {
      idx++;
      t.insert(new RBNode<Point>(p));
      return;
    }
    if (inConvexHull(p)) return;
    RBNode<Point>* node = t.searchGreaterElement(Point(p.x, -1e9));
    if (node && node->key.x == p.x) t.erase(node);
    t.insert(new RBNode<Point>(p));
    RBNode<Point>* minimumNode = t.minimumNode();
    RBNode<Point>* maximumNode = t.maximumNode();
    RBNode<Point>*i, *j;
    node = t.search(p);
    i = t.predeccesor(node);
    if (i) {
      j = t.predeccesor(i);
      while (node->key != minimumNode->key && i->key != minimumNode->key) {
        if (toLeft(node->key, j->key, i->key) <= 0)
          t.erase(t.search(i->key));
        else
          break;
        i = t.search(j->key);
        j = t.predeccesor(i);
      }
    }
    node = t.search(p);
    i = t.successor(node);
    if (i) {
      j = t.successor(i);
      while (node->key != maximumNode->key && i->key != maximumNode->key) {
        if (toLeft(node->key, j->key, i->key) >= 0)
          t.erase(t.search(i->key));
        else
          break;
        i = t.search(j->key);
        j = t.successor(i);
      }
    }
  }
  bool inConvexHull(const Point& p) const {
    if (!t.root) return false;
    RBNode<Point>* minimumNode = t.minimumNode();
    RBNode<Point>* maximumNode = t.maximumNode();
    if (p.x < minimumNode->key.x || p.x > maximumNode->key.x) return false;
    RBNode<Point>* node = t.searchGreaterElement(Point(p.x, -1e9));
    if (node && node->key.x == p.x) return p.y >= node->key.y;
    RBNode<Point>* r = t.searchGreaterElement(p);
    RBNode<Point>* l = t.predeccesor(r);
    return toLeft(p, l->key, r->key) >= 0;
  }
};
int main() {
  int n;
  scanf("%d", &n);
  ConvexHull chUp, chDown;
  for (int i = 0; i < n; ++i) {
    int op;
    int x, y;
    scanf("%d%d%d", &op, &x, &y);
    Point pUp(x, -y), pDown(x, y);
    if (op == 1) {
      chUp.insert(pUp);
      chDown.insert(pDown);
    } else {
      if (chUp.inConvexHull(pUp) && chDown.inConvexHull(pDown))
        printf("YES\n");
      else
        printf("NO\n");
    }
  }
  return 0;
}
