Problem: You are given a set of n vectors on a plane. For each vector you are allowed to multiply any of its coordinates by -1. Thus, each vector vi = (xi, yi) can be transformed into one of the following four vectors:

  * vi1 = (xi, yi), 
  * vi2 = ( - xi, yi), 
  * vi3 = (xi, - yi), 
  * vi4 = ( - xi, - yi). 



You should find two vectors from the set and determine which of their coordinates should be multiplied by -1 so that the absolute value of the sum of the resulting vectors was minimally possible. More formally, you should choose two vectors vi, vj (1 ≤ i, j ≤ n, i ≠ j) and two numbers k1, k2 (1 ≤ k1, k2 ≤ 4), so that the value of the expression |vik1 + vjk2| were minimum.

Input

The first line contains a single integer n (2 ≤ n ≤ 105). Then n lines contain vectors as pairs of integers "xi yi" ( - 10000 ≤ xi, yi ≤ 10000), one pair per line.

Output

Print on the first line four space-separated numbers "i k1 j k2" — the answer to the problem. If there are several variants the absolute value of whose sums is minimum, you can print any of them. 

Examples

Input

5
-7 -3
9 0
-8 6
7 -8
4 -5


Output

3 2 4 2


Input

5
3 2
-4 7
-6 0
-8 4
5 1


Output

3 4 5 4

Note

A sum of two vectors v = (xv, yv) and u = (xu, yu) is vector s = v + u = (xv + xu, yv + yu).

An absolute value of vector v = (x, y) is number <image>. 

In the second sample there are several valid answers, such as:

(3 1 4 2), (3 1 4 4), (3 4 4 1), (3 4 4 3), (4 1 3 2), (4 1 3 4), (4 2 3 1).

Solution (in JAVA):

Solution:

 import java.util.*;
 import java.io.*;

 public class J
 {
    public static void main(String[] args) throws Exception
    {
       new J(new FastScanner(new File("input.txt")));
    }


    int getKValue(vect a, vect b)
    {
       if ((a.x == b.x)&&(a.y == b.y))
          return 1;
       if ((a.x != b.x)&&(a.y == b.y))
          return 2;
       if ((a.x == b.x)&&(a.y != b.y))
          return 3;
       return 4;
    }


    public J(FastScanner in) throws Exception
    {
       PrintWriter out = new PrintWriter("output.txt");
  
       ArrayList<vect> vs = new ArrayList<vect>();
       ArrayList<vect> ts = new ArrayList<vect>();
       ArrayList<vect> rs = new ArrayList<vect>();
       int N = in.nextInt();

       for (int i=0; i<N; i++)
       {
          int x = in.nextInt();
          int y = in.nextInt();
      
          int xx = Math.abs(x);
          int yy = Math.abs(y);


          vs.add(new vect(xx, yy, i));
          
          ts.add(new vect(xx, yy, i));
          rs.add(new vect(x, y, i));
       }


       kdtree solver = new kdtree(vs);


       int best = Integer.MAX_VALUE;
       vect a = null;
       vect b = null;
       for (vect v : ts)
       {
          int rr = solver.kdsearchnn(v);
          if (rr < best)
          {
             a=v;
             b=solver.bb;
             best = rr;
          }
       }


       int k1 = getKValue(ts.get(a.id), rs.get(a.id));
       int k2 = getKValue(ts.get(b.id).invert(), rs.get(b.id));


       //System.out.println(best);
       //System.out.println(a);
       //System.out.println(b);
       out.printf("%d %d %d %d%n", a.id+1, k1, b.id+1, k2);


       out.close();
    }
 }


 class vect implements Comparable<vect>
 {
    int x, y;
    int o;
    
    int id;


    public vect(int i, int j, int iid)
    {
       x=i; y=j; id=iid;
       o=0;
    }

    vect fix()
    {
       vect res = new vect(x,y,id);
       if (o == 1)
          res.swap();
       return res;
    }


    vect invert()
    {
       return new vect(-x, -y, id);
    }

    void swap()
    {
       int tmp = x;
       x = y;
       y = tmp;
       o = 1-o;
    }
    
    public int compareTo(vect rhs)
    {
       if (x == rhs.x)
          return y-rhs.y;
       return x-rhs.x;
    }

   int mag2()
   {
      return x*x+y*y;
   }

    int dist2(vect rhs)
    {
       int xx = x-rhs.x;
       int yy = y-rhs.y;
       return xx*xx+yy*yy;
    }


    public String toString()
    {
       return String.format("%d %d %d", x, y, id);
    }
 }


 class Node
 {
    vect loc;
    Node left;
    Node right;

    public Node(vect v)
    {
       left = right = null;
       loc = v;
    }

    Node near(vect pt)
    {
       if (loc.o == 0)
       {
          if (pt.x == loc.x)
          {
             if (pt.y <= loc.y)
                return left;
             return right;
          }
          if (pt.x < loc.x)
             return left;
          return right;
       }
       else
       {
          if (pt.y == loc.y)
          {
             if (pt.x <= loc.x)
                return left;
             return right;
          }
          if (pt.y < loc.y)
             return left;
          return right;
       }
    }


    Node far(vect pt)
    {
       if (loc.o == 0)
       {
          if (pt.x == loc.x)
          {
             if (pt.y <= loc.y)
                return right;
             return left;
          }
          if (pt.x < loc.x)
             return right;
          return left;
       }
       else
       {
          if (pt.y == loc.y)
          {
             if (pt.x <= loc.x)
                return right;
             return left;
          }
          if (pt.y < loc.y)
             return right;
          return left;
       }
    }


    int axisDist2(vect pt)
    {
       int dx=0;
       if (loc.o == 0)
          dx = pt.x-loc.x;
       else
          dx = pt.y-loc.y;
       return dx*dx;
    }
 }


 class kdtree
 {
    Node root;


    public kdtree(ArrayList<vect> pts)
    {
       vect[] p2 = pts.toArray(new vect[0]);
       root = build(p2, 0, pts.size());
    }


    Node build(vect[] pts, int lo, int hi)
    {
       if (hi <= lo)
          return null;

       for (int i=lo; i<hi; i++)
          pts[i].swap();

       Arrays.sort(pts, lo, hi);
       int mp = (lo+hi)/2;
       Node nn = new Node(pts[mp].fix());
       nn.loc.o = pts[mp].o;
       nn.left = build(pts,lo,mp);
       nn.right = build(pts,mp+1,hi);
       return nn;
    }

    int oo = Integer.MAX_VALUE;
    int best;
    vect bb;
    
    void findBest(Node here, vect pt)
    {
       if (here == null)
          return;

       int d2 = here.loc.dist2(pt);
       if (pt.id != here.loc.id)
       {
          if (best == oo)
          {
             best = d2;
             bb = here.loc;
          }

          if (d2 < best)
          {
             best = d2;
             bb = here.loc;
          }
       }

       Node child = here.near(pt);
       findBest(child, pt);
      
       if ((here.axisDist2(pt) <= best)||(pt.id == here.loc.id))
       {
          child = here.far(pt);
          findBest(child, pt);
       }
    }

    int kdsearchnn(vect pt)
    {
       best = oo;
       bb = null;
       findBest(root, pt);
       return best;
    }
 }

 class FastScanner{
    
    FileInputStream in;
    public FastScanner(File ff) throws Exception
    {
       in = new FileInputStream(ff);
    }


     int nextInt(){
         try{
             int c=in.read();
             if(c==-1) return c;
             while(c!='-'&&(c<'0'||'9'<c)){
                 c=in.read();
                 if(c==-1) return c;
             }
             if(c=='-') return -nextInt();
             int res=0;
             do{
                 res*=10;
                 res+=c-'0';
                 c=in.read();
             }while('0'<=c&&c<='9');
             return res;
         }catch(Exception e){
             return -1;
         }
     }
 }