} inline void addPoint(mii &a, const point &p) { // `no collinear points`
	int x = p.x, y = p.y; mit pnt = a.insert(make_pair(x, y)).first, p1, p2;
	for (pnt->y = y; ; a.erase(p2)) {
		p1 = pnt; if (++p1 == a.end()) break;
		p2 = p1;  if (++p1 == a.end()) break;
		if (det(point(p2) - p, point(p1) - p) < 0) break;
	} for ( ; ; a.erase(p2)) {
		if ((p1 = pnt) == a.begin()) break;
		if (--p1 == a.begin()) break; p2 = p1--;
		if (det(point(p2) - p, point(p1) - p) > 0) break;
	}
}
void topological_sort(int num_nodes)
{
  for (int i = 0; i < num_nodes; ++i) {
    if (incoming_degree.find(i) == incoming_degree.end()) pq.push(i);
  }

  while (!pq.empty()) {
    int u = pq.top(); pq.pop();
    printf("%d ", u);

    for (int i = 0; i < adj_list[u].size(); ++i) {
      if (--incoming_degree[adj_list[u][i]] == 0)
        pq.push(adj_list[u][i]);
    }

    adj_list[u].clear();
  }
}
inline bool checkInside(mii &a, const point &p) { // `border inclusive`
	int x = p.x, y = p.y; mit p1 = a.lower_bound(x);
	if (p1 == a.end()) return false; if (p1->x == x) return y <= p1->y;
	if (p1 == a.begin()) return false; mit p2(p1--);
	return sign(det(p - point(p1), point(p2) - p)) >= 0;
} inline void addPoint(mii &a, const point &p) { // `no collinear points`