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 
5
10 50
10 50
10 50
10 50
10 50
 2
10000 10000
10000 10000
 3
10000 10000
10000 10000
10000 10000
 3
1000 3000
1500 1500
3000 1000
 43
75 16
70 7
75 16
54 2
70 7
54 2
70 7
54 2
70 7
54 2
54 2
70 7
70 7
54 2
70 7
75 16
70 7
54 2
54 2
54 2
54 2
54 2
54 2
75 16
70 7
70 7
54 2
70 7
75 16
54 2
75 16
75 16
54 2
54 2
70 7
70 7
75 16
70 7
70 7
70 7
75 16
75 16
54 2
 1
1 1
 2
1 1
1 1
 44
78 52
75 16
70 7
75 16
54 2
70 7
54 2
70 7
54 2
70 7
54 2
54 2
70 7
70 7
54 2
70 7
75 16
70 7
54 2
54 2
54 2
54 2
54 2
54 2
75 16
70 7
70 7
54 2
70 7
75 16
54 2
75 16
75 16
54 2
54 2
70 7
70 7
75 16
70 7
70 7
70 7
75 16
75 16
54 2
 3
1000 3000
1499 1499
3000 1000
 5
50 50
49 50
50 49
49 49
50 1
 18
82 38
33 69
33 69
33 69
33 69
33 69
82 38
33 69
33 69
33 69
82 38
33 69
33 69
82 38
82 38
33 69
33 69
33 69
 1
10000 9999
 3
1000 3000
1501 1501
3000 1000
 2
1 2
2 1

1 2 3 4 5
 1 2
 1 2 3
 1 2 3
 1 3 16 24 29 31 32 37 41 42
 1
 1 2
 1
 1 3
 1
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 1
 1 2 3
 1 2 

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5010;
struct item {
  int s, t, v, tmp;
} d[maxn];
int pos[maxn], lnk[maxn];
int stx[maxn], sty[maxn];
int n;
void sort(int fi, int la) {
  if (fi >= la) return;
  int i = fi, j = la, g = d[(i + j) >> 1].tmp;
  while (i <= j) {
    while (d[i].tmp < g) i++;
    while (g < d[j].tmp) j--;
    if (i <= j) swap(d[i], d[j]), i++, j--;
  }
  sort(fi, j);
  sort(i, la);
}
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int int_inf = 0x3f3f3f3f;
const long long ll_inf = 0x3f3f3f3f3f3f3f3f;
const int INT_INF = (int)((1ll << 31) - 1);
const double double_inf = 1e30;
const double eps = 1e-14;
inline int readint() {
  int x;
  scanf("%d", &x);
  return x;
}
inline int readstr(char *s) {
  scanf("%s", s);
  return strlen(s);
}
struct Point {
  double x, y;
  Point(double x = 0, double y = 0) : x(x), y(y) {}
};
Point operator+(Point A, Point B) { return Point(A.x + B.x, A.y + B.y); }
Point operator-(Point A, Point B) { return Point(A.x - B.x, A.y - B.y); }
Point operator*(Point A, double p) { return Point(A.x * p, A.y * p); }
Point operator/(Point A, double p) { return Point(A.x / p, A.y / p); }
bool operator<(const Point &a, const Point &b) {
  return a.x < b.x || (a.x == b.x && a.y < b.y);
}
int dcmp(double x) {
  if (abs(x) < eps) return 0;
  return x < 0 ? -1 : 1;
}
bool operator==(const Point &a, const Point &b) {
  return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}
double Dot(Point A, Point B) { return A.x * B.x + A.y * B.y; }
double Len(Point A) { return sqrt(Dot(A, A)); }
double Angle(Point A, Point B) { return acos(Dot(A, B) / Len(A) / Len(B)); }
double Cross(Point A, Point B) { return A.x * B.y - A.y * B.x; }
double Area2(Point A, Point B, Point C) { return Cross(B - A, C - A); }
Point Rotate(Point A, double rad) {
  return Point(A.x * cos(rad) - A.y * sin(rad),
               A.x * sin(rad) + A.y * cos(rad));
}
Point Normal(Point A) {
  double L = Len(A);
  return Point(-A.y / L, A.x / L);
}
void Normallize(Point &A) {
  double L = Len(A);
  A.x /= L, A.y /= L;
}
Point GetLineIntersection(Point P, Point v, Point Q, Point w) {
  Point u = P - Q;
  double t = Cross(w, u) / Cross(v, w);
  return P + v * t;
}
double DistanceToLine(Point P, Point A, Point B) {
  Point v1 = B - A, v2 = P - A;
  return abs(Cross(v1, v2)) / Len(v1);
}
double DistanceToSegment(Point P, Point A, Point B) {
  if (A == B) return Len(P - A);
  Point v1 = B - A, v2 = P - A, v3 = P - B;
  if (dcmp(Dot(v1, v2)) < 0)
    return Len(v2);
  else if (dcmp(Dot(v1, v3)) > 0)
    return Len(v3);
  else
    return abs(Cross(v1, v2)) / Len(v1);
}
Point GetLineProjection(Point P, Point A, Point B) {
  Point v = B - A;
  return A + v * (Dot(v, P - A) / Dot(v, v));
}
bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2) {
  double c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1),
         c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1, a2 - b1);
  return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
}
bool OnSegment(Point p, Point a1, Point a2) {
  return dcmp(Cross(a1 - p, a2 - p)) == 0 && dcmp(Dot(a1 - p, a2 - p)) < 0;
}
Point GetBisector(Point v, Point w) {
  Normallize(v), Normallize(w);
  return Point((v.x + w.x) / 2, (v.y + w.y) / 2);
}
bool OnLine(Point p, Point a1, Point a2) {
  Point v1 = p - a1, v2 = a2 - a1;
  double tem = Cross(v1, v2);
  return dcmp(tem) == 0;
}
struct Line {
  Point p;
  Point v;
  Point point(double t) { return Point(p.x + t * v.x, p.y + t * v.y); }
  Line(Point p, Point v) : p(p), v(v) {}
};
struct Circle {
  Point c;
  double r;
  Circle(Point c, double r) : c(c), r(r) {}
  Circle(int x, int y, int _r) {
    c = Point(x, y);
    r = _r;
  }
  Point point(double a) { return Point(c.x + cos(a) * r, c.y + sin(a) * r); }
};
int GetLineCircleIntersection(Line L, Circle C, double &t1, double &t2,
                              std::vector<Point> &sol) {
  double a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y - C.c.y;
  double e = a * a + c * c, f = 2 * (a * b + c * d),
         g = b * b + d * d - C.r * C.r;
  double delta = f * f - 4 * e * g;
  if (dcmp(delta) < 0) return 0;
  if (dcmp(delta) == 0) {
    t1 = t2 = -f / (2 * e);
    sol.push_back(L.point(t1));
    return 1;
  }
  t1 = (-f - sqrt(delta)) / (2 * e);
  sol.push_back(L.point(t1));
  t2 = (-f + sqrt(delta)) / (2 * e);
  sol.push_back(L.point(t2));
  return 2;
}
double angle(Point v) { return atan2(v.y, v.x); }
int GetCircleCircleIntersection(Circle C1, Circle C2, std::vector<Point> &sol) {
  double d = Len(C1.c - C2.c);
  if (dcmp(d) == 0) {
    if (dcmp(C1.r - C2.r) == 0) return -1;
    return 0;
  }
  if (dcmp(C1.r + C2.r - d) < 0) return 0;
  if (dcmp(abs(C1.r - C2.r) - d) > 0) return 0;
  double a = angle(C2.c - C1.c);
  double da = acos((C1.r * C1.r + d * d - C2.r * C2.r) / (2 * C1.r * d));
  Point p1 = C1.point(a - da), p2 = C1.point(a + da);
  sol.push_back(p1);
  if (p1 == p2) return 1;
  sol.push_back(p2);
  return 2;
}
int GetPointCircleTangents(Point p, Circle C, Point *v) {
  Point u = C.c - p;
  double dist = Len(u);
  if (dist < C.r)
    return 0;
  else if (dcmp(dist - C.r) == 0) {
    v[0] = Rotate(u, acos(-1.) / 2);
    return 1;
  } else {
    double ang = asin(C.r / dist);
    v[0] = Rotate(u, -ang);
    v[1] = Rotate(u, +ang);
    return 2;
  }
}
int GetCircleCircleTangents(Circle A, Circle B, Point *a, Point *b) {
  int cnt = 0;
  if (A.r < B.r) {
    std::swap(A, B);
    std::swap(a, b);
  }
  int d2 =
      (A.c.x - B.c.x) * (A.c.x - B.c.x) + (A.c.y - B.c.y) * (A.c.y - B.c.y);
  int rdiff = A.r - B.r;
  int rsum = A.r + B.r;
  if (d2 < rdiff * rdiff) return 0;
  double base = atan2(B.c.y - A.c.y, B.c.x - A.c.x);
  if (d2 == 0 && A.r == B.r) return -1;
  if (d2 == rdiff * rdiff) {
    a[cnt] = A.point(base);
    b[cnt] = B.point(base);
    cnt++;
    return 1;
  }
  double ang = acos((A.r - B.r) / sqrt(d2));
  a[cnt] = A.point(base + ang);
  b[cnt++] = B.point(base + ang);
  a[cnt] = A.point(base - ang);
  b[cnt++] = B.point(base - ang);
  if (d2 == rsum * rsum) {
    a[cnt] = A.point(base);
    b[cnt++] = B.point(base + acos(-1.));
  } else if (d2 > rsum * rsum) {
    double ang = acos((A.r + B.r) / sqrt(d2));
    a[cnt] = A.point(base + ang);
    b[cnt++] = B.point(base + ang + acos(-1.));
    a[cnt] = A.point(base - ang);
    b[cnt++] = B.point(base - ang + acos(-1.));
  }
  return cnt;
}
Point ReadPoint() {
  double x, y;
  scanf("%lf%lf", &x, &y);
  return Point(x, y);
}
Circle ReadCircle() {
  double x, y, r;
  scanf("%lf%lf%lf", &x, &y, &r);
  return Circle(x, y, r);
}
struct Point3 {
  double x, y, z;
  Point3(double x = 0, double y = 0, double z = 0) : x(x), y(y), z(z) {}
};
Point3 operator+(Point3 A, Point3 B) {
  return Point3(A.x + B.x, A.y + B.y, A.z + B.z);
}
Point3 operator-(Point3 A, Point3 B) {
  return Point3(A.x - B.x, A.y - B.y, A.z - B.z);
}
Point3 operator*(Point3 A, double p) {
  return Point3(A.x * p, A.y * p, A.z * p);
}
Point3 operator/(Point3 A, double p) {
  return Point3(A.x / p, A.y / p, A.z / p);
}
double Dot3(Point3 A, Point3 B) { return A.x * B.x + A.y * B.y + A.z * B.z; }
double Len3(Point3 A) { return sqrt(Dot3(A, A)); }
double Angle3(Point3 A, Point3 B) {
  return acos(Dot3(A, B) / Len3(A) / Len3(B));
}
double DistanceToPlane(const Point3 &p, const Point3 &p0, const Point3 &n) {
  return abs(Dot3(p - p0, n));
}
Point3 GetPlaneProjection(const Point3 &p, const Point3 &p0, const Point3 &n) {
  return p - n * Dot3(p - p0, n);
}
Point3 GetLinePlaneIntersection(Point3 p1, Point3 p2, Point3 p0, Point3 n) {
  Point3 v = p2 - p1;
  double t = (Dot3(n, p0 - p1) / Dot3(n, p2 - p1));
  return p1 + v * t;
}
Point3 Cross(Point3 A, Point3 B) {
  return Point3(A.y * B.z - A.z * B.y, A.z * B.x - A.x * B.z,
                A.x * B.y - A.y * B.x);
}
double Area3(Point3 A, Point3 B, Point3 C) { return Len3(Cross(B - A, C - A)); }
class cmpt {
 public:
  bool operator()(const int &x, const int &y) const { return x > y; }
};
int num[100005], mlen, r;
int gcd(int a, int b) {
  while (a % b != 0) a %= b, swap(a, b);
  return b;
}
int cal(int lim) {
  if (mlen % lim != 0) return 0;
  int tmp = r - lim - n / lim;
  if (tmp % (n / lim) != 0) return 0;
  tmp /= (n / lim);
  return tmp / n + 1;
}
int Rand(int x, int o) {
  if (!x) return 0;
  int tem = (int)((double)rand() / RAND_MAX * x) % x;
  return o ? tem + 1 : tem;
}
const int N = 2 * 1e5 + 5;
struct Dt {
  double x, y;
  int id;
  Dt() {}
  Dt(int _x, int _y, int _id) {
    x = _x;
    y = _y;
    id = _id;
  }
  bool operator<(const Dt t) const {
    if (x == t.x) {
      return y < t.y;
    }
    return x < t.x;
  }
} a[N];
priority_queue<Dt> q;
int ans[N], cnt = 0;
vector<int> tab[N];
double xl[N];
void gao(Dt now) {
  if (cnt == 0) {
    tab[cnt].push_back(now.id);
    ans[cnt++] = now.id;
    return;
  }
  double tmp;
  int pre = ans[cnt - 1];
  if (now.y == a[pre].y) {
    if (now.x == a[pre].x) {
      tab[cnt - 1].push_back(now.id);
      return;
    }
    return;
  }
  while (cnt > 1) {
    pre = ans[cnt - 1];
    tmp = (now.x - a[pre].x) * now.y * a[pre].y /
          ((a[pre].y - now.y) * a[pre].x * now.x);
    if (tmp < xl[pre]) {
      tab[cnt - 1].clear();
      --cnt;
    } else
      break;
  }
  pre = ans[cnt - 1];
  tmp = (now.x - a[pre].x) * now.y * a[pre].y /
        ((a[pre].y - now.y) * a[pre].x * now.x);
  xl[now.id] = tmp;
  tab[cnt].push_back(now.id);
  ans[cnt++] = now.id;
}
void work() {
  int n;
  double u, v;
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    scanf("%lf%lf", &u, &v);
    a[i] = Dt(u, v, i);
    q.push(Dt(u, v, i));
  }
  double _max = 0;
  while (!q.empty()) {
    while (!q.empty() && q.top().y < _max) {
      q.pop();
    }
    if (q.empty()) break;
    Dt now = q.top();
    q.pop();
    gao(now);
    _max = max(_max, now.y);
  }
  int cc = 0;
  for (int i = 0; i < cnt; ++i) {
    for (int j = 0; j < tab[i].size(); ++j) {
      ans[cc++] = tab[i][j];
    }
  }
  sort(ans, ans + cc);
  for (int i = 0; i < cc; ++i) {
    printf("%d%c", ans[i] + 1, i == cc - 1 ? '\n' : ' ');
  }
}
void data_gen() {
  srand(time(0));
  freopen("in.txt", "w", stdout);
  int kases = 10;
  printf("%d\n", kases);
  while (kases--) {
    int sz = 2e4;
    int m = 1e5;
    printf("%d %d\n", sz, m);
    for (int i = (1); i <= (sz); i++) printf("%d ", Rand(100, 1));
    printf("\n");
    for (int i = (1); i <= (sz); i++) printf("%d ", Rand(1e9, 1));
    printf("\n");
    for (int i = (1); i <= (m); i++) {
      int l = Rand(sz, 1);
      int r = Rand(sz, 1);
      int c = Rand(1e9, 1);
      printf("%d %d %d %d\n", l, r, c, Rand(100, 1));
    }
  }
}
struct cmpx {
  bool operator()(int x, int y) { return x > y; }
};
int debug = 0;
int m;
char mt[10][10];
bool mt2[30][30];
int dx[] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {-1, 0, 1, -1, 1, -1, 0, 1};
bool in_range(int x, int y) { return x >= 1 && x <= n && y >= 1 && y <= m; }
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  work();
  return 0;
}
