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 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Comparator;

/* Test Case 1
7
5 1
4 3
3 4
2 6
3 5
4 2
1 5
Ans = 1 2 4 5
*/

/* Test Case 2
6
3 4
5 2
4 2
6 1
2 5
4 4
Ans = 2 4 5 6
*/

public class Pashmaks
{
  static class Point implements Comparable<Point>{
    int x, y, id;
    boolean min, hull;

    Point(int s_, int r_, int id_){
      this.x = s_;
      this.y = r_;
      this.id = id_;
      min = false;
      hull = false;
    }

    boolean equals(Point p){
      return x == p.x && y == p.y;
    }

    @Override public int compareTo(Point p){
      return cross(origin, this, p);
    }

    static Comparator<Point> xyCompare = new Comparator<Point>() {
      public int compare(Point a, Point b) {
        return b.x != a.x ? b.x - a.x : b.y - a.y;
      }
    };

    public static Comparator<Point> idCompare = new Comparator<Point>(){
      public int compare(Point p, Point q){
        return p.id - q.id;
      }
    };

    public String toString() {
      return id + " -> " + x + " " + y;
    }
  }

  static Point origin = new Point(0,0,0);

  static long partOfHull(Point a, Point b, Point c) {
    return (long)(c.x * (a.x - b.x)) * (b.y * (a.y - c.y))
            - (long)(b.x * (a.x - c.x)) * (c.y * (a.y - b.y));
  }

  static int cross(Point a, Point b, Point c){
    return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
  }

  // Used for debugging
  static void printArray(Point[] arr, int n, PrintWriter pw){
    for(int i = 0; i < n; i++)
      pw.println(arr[i].toString());
    pw.println();
  }

  // Print elements of array if they are marked part of the hull in one line
  static void printResultArray(Point[] arr, int n, PrintWriter pw) {
    for(int i = 0; i < n; i++){
      if(arr[i].hull) pw.print(arr[i].id + " ");
    }
  }

  public static void main (String[] args) throws java.lang.Exception
  {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    PrintWriter pw = new PrintWriter(System.out);

    int n = Integer.parseInt(br.readLine());
    Point[] peeps = new Point[n];
    //Point maxY = new Point(0,0,0);
    //Point maxX = new Point(0,0,0);

    for(int i = 0; i < n; i++) {
      String[] line = br.readLine().split(" ");
      // S == X, R == Y
      peeps[i] = new Point(Integer.parseInt(line[0]),
              Integer.parseInt(line[1]),
              i+1);
      //if(peeps[i].x > maxX.x) maxX = peeps[i];
      //if(peeps[i].y > maxY.y) maxY = peeps[i];
    }
    //origin = new Point(maxY.x, maxX.y, 0);
    Arrays.sort(peeps, Point.xyCompare);

    // A point is minimal if it is to the right and below another point
    // This will reduce the number of points to look at by only getting the ones on the outer edge
    // Start by setting the lowest X and highest Y point to min and start from there
    peeps[0].min = true;
    for (int i = 0, j = 1; j < n; j++) {
      if (peeps[j].x < peeps[i].x && peeps[j].y > peeps[i].y) {
        peeps[j].min = true;
        i = j;
      }
    }

    /*ArrayList<Point> possible = new ArrayList<>();
    for(int i = 0; i < n; i++) {
      if(peeps[i].x >= origin.x && peeps[i].y >= origin.y) possible.add(peeps[i]);
    }
    peeps = possible.toArray(new Point[possible.size()]);
    n = peeps.length;*/
    //printArray(peeps,n,pw);

    // Winners will be part of the convex hull
    Point[] hull = new Point[n];
    int size = 0;
    for(int i = 0; i < n; i++){
      Point p = peeps[i];
      if(!p.min) continue;
      while(true){
        if(size < 2) break; // Not enough in [] to compare

        Point a = hull[size - 2];
        Point b = hull[size - 1];
        if(partOfHull(a,b,p) >= 0) break;
        size--;
      }
      hull[size++] = p;
    }
    for(int i = 0; i < size; i++){
      hull[i].hull = true;
    }
    // Catch any duplicate points that could have been removed during the convex hull creation
    for(int i = 1; i < n; i++){
      if(peeps[i-1].hull && peeps[i-1].equals(peeps[i])) peeps[i].hull = true;
    }
    // Sort by ids now
    Arrays.sort(peeps, Point.idCompare);
    // Only print values that are marked as in the hull
    printResultArray(peeps,n,pw);
    pw.close();
  }
}