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;
using Int = long long;
template <typename T1, typename T2>
inline void chmin(T1 &a, T2 b) {
  if (a > b) a = b;
}
template <typename T1, typename T2>
inline void chmax(T1 &a, T2 b) {
  if (a < b) a = b;
}
struct FastIO {
  FastIO() {
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
} fastio_beet;
static const int CCW_COUNTER_CLOCKWISE = 1;
static const int CCW_CLOCKWISE = -1;
static const int CCW_ONLINE_BACK = 2;
static const int CCW_ONLINE_FRONT = -2;
static const int CCW_ON_SEGMENT = 0;
static const int ICC_SEPERATE = 4;
static const int ICC_CIRCUMSCRIBE = 3;
static const int ICC_INTERSECT = 2;
static const int ICC_INSCRIBE = 1;
static const int ICC_CONTAIN = 0;
struct Point {
  long double x, y;
  Point() {}
  Point(long double x, long double y) : x(x), y(y) {}
  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(long double k) { return Point(x * k, y * k); }
  Point operator/(long double k) { return Point(x / k, y / k); }
  long double norm() { return x * x + y * y; }
  long double abs() { return sqrt(norm()); }
  bool operator<(const Point &p) const { return x != p.x ? x < p.x : y < p.y; }
  bool operator==(const Point &p) const {
    return fabs(x - p.x) < (1e-20) && fabs(y - p.y) < (1e-20);
  }
};
struct EndPoint {
  Point p;
  int seg, st;
  EndPoint() {}
  EndPoint(Point p, int seg, int st) : p(p), seg(seg), st(st) {}
  bool operator<(const EndPoint &ep) const {
    if (p.y == ep.p.y) return st < ep.st;
    return p.y < ep.p.y;
  }
};
istream &operator>>(istream &is, Point &p) {
  is >> p.x >> p.y;
  return is;
}
ostream &operator<<(ostream &os, Point p) {
  os << fixed << setprecision(12) << p.x << " " << p.y;
  return os;
}
bool sort_x(Point a, Point b) { return a.x != b.x ? a.x < b.x : a.y < b.y; }
bool sort_y(Point a, Point b) { return a.y != b.y ? a.y < b.y : a.x < b.x; }
istream &operator>>(istream &is, vector<Point> &p) {
  for (int i = 0; i < (int)p.size(); i++) is >> p[i];
  return is;
}
struct Segment {
  Point p1, p2;
  Segment() {}
  Segment(Point p1, Point p2) : p1(p1), p2(p2) {}
};
istream &operator>>(istream &is, Segment &s) {
  is >> s.p1 >> s.p2;
  return is;
}
struct Circle {
  Point c;
  long double r;
  Circle() {}
  Circle(Point c, long double r) : c(c), r(r) {}
};
istream &operator>>(istream &is, Circle &c) {
  is >> c.c >> c.r;
  return is;
}
long double norm(Point a) { return a.x * a.x + a.y * a.y; }
long double abs(Point a) { return sqrt(norm(a)); }
long double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }
long double cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }
Point orth(Point p) { return Point(-p.y, p.x); }
bool isOrthogonal(Point a, Point b) {
  return (fabs((dot(a, b)) - (0.0)) < (1e-20));
}
bool isOrthogonal(Point a1, Point a2, Point b1, Point b2) {
  return isOrthogonal(a1 - a2, b1 - b2);
}
bool isOrthogonal(Segment s1, Segment s2) {
  return (fabs((dot(s1.p2 - s1.p1, s2.p2 - s2.p1)) - (0.0)) < (1e-20));
}
bool isParallel(Point a, Point b) {
  return (fabs((cross(a, b)) - (0.0)) < (1e-20));
}
bool isParallel(Point a1, Point a2, Point b1, Point b2) {
  return isParallel(a1 - a2, b1 - b2);
}
bool isParallel(Segment s1, Segment s2) {
  return (fabs((cross(s1.p2 - s1.p1, s2.p2 - s2.p1)) - (0.0)) < (1e-20));
}
Point project(Segment s, Point p) {
  Point base = s.p2 - s.p1;
  long double r = dot(p - s.p1, base) / norm(base);
  return s.p1 + base * r;
}
Point reflect(Segment s, Point p) { return p + (project(s, p) - p) * 2.0; }
long double arg(Point p) { return atan2(p.y, p.x); }
Point polar(long double a, long double r) {
  return Point(cos(r) * a, sin(r) * a);
}
int ccw(Point p0, Point p1, Point p2);
bool intersectSS(Point p1, Point p2, Point p3, Point p4);
bool intersectSS(Segment s1, Segment s2);
bool intersectPS(vector<Point> p, Segment l);
int intersectCC(Circle c1, Circle c2);
bool intersectSC(Segment s, Circle c);
long double getDistanceLP(Segment l, Point p);
long double getDistanceSP(Segment s, Point p);
long double getDistanceSS(Segment s1, Segment s2);
Point getCrossPointSS(Segment s1, Segment s2);
Point getCrossPointLL(Segment l1, Segment l2);
vector<Point> getCrossPointCL(Circle c, Segment l);
vector<Point> getCrossPointCC(Circle c1, Circle c2);
int contains(vector<Point> g, Point p);
vector<Point> andrewScan(vector<Point> s);
vector<Point> convex_hull(vector<Point> ps);
long double diameter(vector<Point> s);
bool isConvex(vector<Point> p);
long double area(vector<Point> s);
vector<Point> convexCut(vector<Point> p, Segment l);
Segment bisector(Point p1, Point p2);
Point translate(Point v, long double theta);
vector<Segment> corner(Segment l1, Segment l2);
vector<vector<int> > segmentArrangement(vector<Segment> &ss, vector<Point> &ps);
int ccw(Point p0, Point p1, Point p2) {
  Point a = p1 - p0;
  Point b = p2 - p0;
  if (cross(a, b) > (1e-20)) return CCW_COUNTER_CLOCKWISE;
  if (cross(a, b) < -(1e-20)) return CCW_CLOCKWISE;
  if (dot(a, b) < -(1e-20)) return CCW_ONLINE_BACK;
  if (a.norm() < b.norm()) return CCW_ONLINE_FRONT;
  return CCW_ON_SEGMENT;
}
bool intersectSS(Point p1, Point p2, Point p3, Point p4) {
  return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
          ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0);
}
bool intersectSS(Segment s1, Segment s2) {
  return intersectSS(s1.p1, s1.p2, s2.p1, s2.p2);
}
bool intersectPS(vector<Point> p, Segment l) {
  int n = p.size();
  for (int i = 0; i < n; i++)
    if (intersectSS(Segment(p[i], p[(i + 1) % n]), l)) return 1;
  return 0;
}
int intersectCC(Circle c1, Circle c2) {
  if (c1.r < c2.r) swap(c1, c2);
  long double d = abs(c1.c - c2.c);
  long double r = c1.r + c2.r;
  if ((fabs((d) - (r)) < (1e-20))) return ICC_CIRCUMSCRIBE;
  if (d > r) return ICC_SEPERATE;
  if ((fabs((d + c2.r) - (c1.r)) < (1e-20))) return ICC_INSCRIBE;
  if (d + c2.r < c1.r) return ICC_CONTAIN;
  return ICC_INTERSECT;
}
bool intersectSC(Segment s, Circle c) { return getDistanceSP(s, c.c) <= c.r; }
int intersectCS(Circle c, Segment s) {
  if (norm(project(s, c.c) - c.c) - c.r * c.r > (1e-20)) return 0;
  long double d1 = abs(c.c - s.p1), d2 = abs(c.c - s.p2);
  if (d1 < c.r + (1e-20) && d2 < c.r + (1e-20)) return 0;
  if ((d1 < c.r - (1e-20) && d2 > c.r + (1e-20)) ||
      (d1 > c.r + (1e-20) && d2 < c.r - (1e-20)))
    return 1;
  Point h = project(s, c.c);
  if (dot(s.p1 - h, s.p2 - h) < 0) return 2;
  return 0;
}
long double getDistanceLP(Segment l, Point p) {
  return abs(cross(l.p2 - l.p1, p - l.p1) / abs(l.p2 - l.p1));
}
long double getDistanceSP(Segment s, Point p) {
  if (dot(s.p2 - s.p1, p - s.p1) < 0.0) return abs(p - s.p1);
  if (dot(s.p1 - s.p2, p - s.p2) < 0.0) return abs(p - s.p2);
  return getDistanceLP(s, p);
}
long double getDistanceSS(Segment s1, Segment s2) {
  if (intersectSS(s1, s2)) return 0.0;
  return min(min(getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2)),
             min(getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2)));
}
Point getCrossPointSS(Segment s1, Segment s2) {
  for (int k = 0; k < 2; k++) {
    if (getDistanceSP(s1, s2.p1) < (1e-20)) return s2.p1;
    if (getDistanceSP(s1, s2.p2) < (1e-20)) return s2.p2;
    swap(s1, s2);
  }
  Point base = s2.p2 - s2.p1;
  long double d1 = abs(cross(base, s1.p1 - s2.p1));
  long double d2 = abs(cross(base, s1.p2 - s2.p1));
  long double t = d1 / (d1 + d2);
  return s1.p1 + (s1.p2 - s1.p1) * t;
}
Point getCrossPointLL(Segment l1, Segment l2) {
  long double a = cross(l1.p2 - l1.p1, l2.p2 - l2.p1);
  long double b = cross(l1.p2 - l1.p1, l1.p2 - l2.p1);
  if (abs(a) < (1e-20) && abs(b) < (1e-20)) return l2.p1;
  return l2.p1 + (l2.p2 - l2.p1) * (b / a);
}
vector<Point> getCrossPointCL(Circle c, Segment l) {
  vector<Point> ps;
  Point pr = project(l, c.c);
  Point e = (l.p2 - l.p1) / abs(l.p2 - l.p1);
  if ((fabs((getDistanceLP(l, c.c)) - (c.r)) < (1e-20))) {
    ps.emplace_back(pr);
    return ps;
  }
  long double base = sqrt(c.r * c.r - norm(pr - c.c));
  ps.emplace_back(pr + e * base);
  ps.emplace_back(pr - e * base);
  return ps;
}
vector<Point> getCrossPointCS(Circle c, Segment s) {
  Segment l(s);
  vector<Point> res = getCrossPointCL(c, l);
  if (intersectCS(c, s) == 2) return res;
  if (res.size() > 1u) {
    if (dot(l.p1 - res[0], l.p2 - res[0]) > 0) swap(res[0], res[1]);
    res.pop_back();
  }
  return res;
}
vector<Point> getCrossPointCC(Circle c1, Circle c2) {
  vector<Point> p(2);
  long double d = abs(c1.c - c2.c);
  long double a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
  long double t = arg(c2.c - c1.c);
  p[0] = c1.c + polar(c1.r, t + a);
  p[1] = c1.c + polar(c1.r, t - a);
  return p;
}
int contains(vector<Point> g, Point p) {
  int n = g.size();
  bool x = false;
  for (int i = 0; i < n; i++) {
    Point a = g[i] - p, b = g[(i + 1) % n] - p;
    if (fabs(cross(a, b)) < (1e-20) && dot(a, b) < (1e-20)) return 1;
    if (a.y > b.y) swap(a, b);
    if (a.y < (1e-20) && (1e-20) < b.y && cross(a, b) > (1e-20)) x = !x;
  }
  return (x ? 2 : 0);
}
vector<Point> andrewScan(vector<Point> s) {
  vector<Point> l;
  if (s.size() < 3) return s;
  sort(s.begin(), s.end());
  l.push_back(s[s.size() - 1]);
  l.push_back(s[s.size() - 2]);
  for (int i = s.size() - 3; i >= 0; i--) {
    for (int n = l.size();
         n >= 2 && (ccw(l[n - 2], l[n - 1], s[i]) != CCW_CLOCKWISE &&
                    ccw(l[n - 2], l[n - 1], s[i]) != CCW_ONLINE_FRONT);
         n--) {
      l.pop_back();
    }
    l.push_back(s[i]);
  }
  return l;
}
signed main() {
  int n;
  cin >> n;
  vector<int> rs(n), ss(n);
  for (int i = 0; i < n; i++) cin >> rs[i] >> ss[i];
  using P = pair<int, int>;
  set<P> uku;
  int num = 0;
  vector<Point> qs(n);
  for (int i = 0; i < n; i++) {
    if (uku.count(P(rs[i], ss[i]))) continue;
    uku.emplace(rs[i], ss[i]);
    qs[num].x = 1.0 / rs[i];
    qs[num].y = 1.0 / ss[i];
    num++;
  }
  qs.resize(num);
  qs.emplace_back(1e18, 0);
  qs.emplace_back(0, 1e18);
  qs = andrewScan(qs);
  using P = pair<int, int>;
  set<P> cand;
  for (auto p : qs) {
    if (p.x == 0 || p.y == 0) continue;
    int a = round(1.0 / p.x);
    int b = round(1.0 / p.y);
    cand.emplace(a, b);
  }
  vector<int> ans;
  for (int i = 0; i < n; i++)
    if (cand.count(P(rs[i], ss[i]))) ans.emplace_back(i);
  for (int i = 0; i < (int)ans.size(); i++) {
    if (i) cout << " ";
    cout << ans[i] + 1;
  }
  cout << endl;
  return 0;
}
