Tavas is a cheerleader in the new sports competition named "Pashmaks".

<image>

This competition consists of two part: swimming and then running. People will immediately start running R meters after they finished swimming exactly S meters. A winner is a such person that nobody else finishes running before him/her (there may be more than one winner).

Before the match starts, Tavas knows that there are n competitors registered for the match. Also, he knows that i-th person's swimming speed is si meters per second and his/her running speed is ri meters per second. Unfortunately, he doesn't know the values of R and S, but he knows that they are real numbers greater than 0.

As a cheerleader, Tavas wants to know who to cheer up. So, he wants to know all people that might win. We consider a competitor might win if and only if there are some values of R and S such that with these values, (s)he will be a winner.

Tavas isn't really familiar with programming, so he asked you to help him.

Input

The first line of input contains a single integer n (1 ≤ n ≤ 2 × 105).

The next n lines contain the details of competitors. i-th line contains two integers si and ri (1 ≤ si, ri ≤ 104).

Output

In the first and the only line of output, print a sequence of numbers of possible winners in increasing order.

Examples

Input

3
1 3
2 2
3 1


Output

1 2 3 


Input

3
1 2
1 1
2 1


Output

1 3 
#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-12;
inline int cmp(double a, double b) {
  return (a < b - EPS) ? -1 : ((a > b + EPS) ? 1 : 0);
}
struct Point {
  double x, y;
  int id;
  Point(double x = 0.0, double y = 0.0, int id = 0) : x(x), y(y), id(id) {}
  Point operator+(Point a) { return Point(x + a.x, y + a.y); }
  Point operator-(Point a) { return Point(x - a.x, y - a.y); }
  Point operator*(double k) { return Point(x * k, y * k); }
  Point operator/(double k) { return Point(x / k, y / k); }
  double operator*(Point a) { return x * a.x + y * a.y; }
  double operator%(Point a) { return x * a.y - y * a.x; }
  int cmp(Point q) const {
    if (int t = ::cmp(x, q.x)) return t;
    return ::cmp(y, q.y);
  }
  bool operator>(Point q) const { return cmp(q) > 0; }
  bool operator<(Point q) const { return cmp(q) < 0; }
  bool operator==(Point q) const { return cmp(q) == 0; }
  bool operator>=(Point q) const { return cmp(q) >= 0; }
  bool operator<=(Point q) const { return cmp(q) <= 0; }
  bool operator!=(Point q) const { return cmp(q) != 0; }
  Point conj() { return Point(x, -y); }
  double norm() { return x * x + y * y; }
  double len() { return sqrt(norm()); }
  Point rotate(double alpha) {
    double cosa = cos(alpha), sina = sin(alpha);
    return Point(x * cosa - y * sina, x * sina + y * cosa);
  }
};
double cross(Point p, Point q) { return p.x * q.y - p.y * q.x; }
double area2(Point a, Point b, Point c) {
  return cross(a, b) + cross(b, c) + cross(c, a);
}
int ccw(Point a, Point b, Point c) {
  double t = cross(b - a, c - a);
  if (fabs(t) < EPS)
    return 0;
  else if (t < 0)
    return -1;
  else
    return 1;
}
void ConvexHull(vector<Point> &pts) {
  sort(pts.begin(), pts.end());
  pts.erase(unique(pts.begin(), pts.end()), pts.end());
  vector<Point> up, dn;
  for (int i = 0; i < pts.size(); i++) {
    while (up.size() > 1 && area2(up[up.size() - 2], up.back(), pts[i]) >= 0)
      up.pop_back();
    while (dn.size() > 1 && area2(dn[dn.size() - 2], dn.back(), pts[i]) <= 0)
      dn.pop_back();
    up.push_back(pts[i]);
    dn.push_back(pts[i]);
  }
  pts = dn;
  for (int i = (int)up.size() - 2; i >= 1; i--) pts.push_back(up[i]);
}
int bit[10111];
const int MN = 200111;
bool can[MN];
void update(int u, int val) {
  while (u <= 10000) {
    bit[u] = max(bit[u], val);
    u += ((u) & (-(u)));
  }
}
int get(int u) {
  int res = 0;
  while (u > 0) {
    res = max(res, bit[u]);
    u -= ((u) & (-(u)));
  }
  return res;
}
pair<int, int> input[MN];
int main() {
  ios ::sync_with_stdio(false);
  int n;
  while (scanf("%d", &n) == 1) {
    vector<Point> a;
    memset(bit, 0, sizeof bit);
    for (int i = (1), _b = (n); i <= _b; i++) {
      int x, y;
      scanf("%d%d", &x, &y);
      a.push_back(Point(1.0 / x, 1.0 / y, i));
      input[i] = make_pair(10001 - x, y);
      update(input[i].first, input[i].second);
    }
    for (int i = (1), _b = (n); i <= _b; i++) {
      if (get(input[i].first - 1) >= input[i].second)
        can[i] = false;
      else if (get(input[i].first) > input[i].second)
        can[i] = false;
      else
        can[i] = true;
    }
    ConvexHull(a);
    set<int> res;
    int sz = a.size();
    Point O(0, 0, 0);
    for (int i = 0, _a = (sz); i < _a; i++) {
      Point y = a[i];
      Point x = a[(i - 1 + sz) % sz];
      Point xx = a[(i - 2 + sz + sz) % sz];
      Point z = a[(i + 1) % sz];
      Point zz = a[(i + 2) % sz];
      if (ccw(x, y, z) * ccw(x, y, O) <= 0 && ccw(x, y, xx) * ccw(x, y, O) <= 0)
        res.insert(a[i].id);
      if (ccw(y, z, x) * ccw(y, z, O) <= 0 && ccw(y, z, zz) * ccw(y, z, O) <= 0)
        res.insert(a[i].id);
    }
    set<pair<int, int> > all;
    for (int x : res)
      if (can[x]) all.insert(input[x]);
    for (int i = (1), _b = (n); i <= _b; i++)
      if (all.count(input[i])) cout << i << ' ';
    cout << endl;
  }
  return 0;
}
