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.awt.Point;
import java.io.*;
import java.math.BigInteger;
import java.util.*;
import java.util.Map.Entry;

import static java.lang.Math.*;

public class J {
       
        final boolean ONLINE_JUDGE = System.getProperty("ONLINE_JUDGE")!=null;
        BufferedReader in;
        PrintWriter out;
        StringTokenizer tok = new StringTokenizer("");
       
        void init() throws FileNotFoundException{
                        in = new BufferedReader(new FileReader("input.txt"));
                        out = new PrintWriter("output.txt");
        }
       
        String readString() throws IOException{
                while(!tok.hasMoreTokens()){
                        tok = new StringTokenizer(in.readLine());
                }
                return tok.nextToken();
        }
       
        int readInt() throws IOException{
                return Integer.parseInt(readString());
        }
       
        long readLong() throws IOException{
                return Long.parseLong(readString());
        }
       
        double readDouble() throws IOException{
                return Double.parseDouble(readString());
        }
       
        public static void main(String[] args){
                new J().run();
        }
       
        public void run(){
                try{
                        long t1 = System.currentTimeMillis();
                        init();
                        solve();
                        out.close();
                        long t2 = System.currentTimeMillis();
                        System.err.println("Time = "+(t2-t1));
                }catch (Exception e){
                        e.printStackTrace(System.err);
                        System.exit(-1);
                }
        }
       
        class Point{
            
            long x, y;
            int k, i;
            public Point(long x, long y, int k, int i) {
                this.x = x;
                this.y = y;
                this.k = k;
                this.i = i;
            }
            @Override
            public String toString() {
                return "("+x+","+y+")";
            }
            @Override
            public int hashCode() {
                return i;
            }
            @Override
            public boolean equals(Object obj) {
                Point other = (Point) obj;
                if (i != other.i)
                    return false;
                if (k != other.k)
                    return false;
                if (x != other.x)
                    return false;
                if (y != other.y)
                    return false;
                return true;
            }
    
        }
        
        class Answer {
            Point p, q;
            long res;
            public Answer(J.Point p, J.Point q, long res) {
                this.p = p;
                this.q = q;
                this.res = res;
            }
        }
        
        long dist(Point p, Point q) {
            long dx = p.x - q.x;
            long dy = p.y - q.y;
            return dx*dx + dy*dy;
        }
        
        Answer go(Point[] px, Point[] py) {
            int n = px.length;
            if (n <= 3) {
                long min = Long.MAX_VALUE;
                int ii = -1, jj = -1;
                for (int i = 0; i < n; i++) {
                    for (int j = i+1; j < n; j++) {
                        long D = dist(px[i], px[j]);
                        if (min > D) {
                            min = D;
                            ii = i;
                            jj = j;
                        }
                    }
                }
                return new Answer(px[ii], px[jj], min);
            }
            int nn = n/2;
            HashSet<Integer> set = new HashSet<Integer>();
            for (int i = 0; i < nn; i++) {
                set.add(px[i].i);
            }
            Point[] pxL = new Point[nn];
            Point[] pxR = new Point[n - nn];
            Point[] pyL = new Point[nn];
            Point[] pyR = new Point[n - nn];
            for (int i = 0; i < nn; i++) {
                pxL[i] = px[i];
            }
            for (int i = nn, j = 0; i < n; i++, j++) {
                pxR[j] = px[i];
            }
            for (int i = 0, LL = 0, RR = 0; i < n; i++) {
                if (set.contains(py[i].i)) {
                    pyL[LL++] = py[i];
                } else {
                    pyR[RR++] = py[i];
                }
            }
            Answer ansL = go(pxL, pyL);
            Answer ansR = go(pxR, pyR);
            Answer best = ansL.res > ansR.res ? ansR : ansL;
            return merge(px, py, best, pxR[0].x);
        }
        
        Answer merge(Point[] px, Point[] py, Answer best, long X) {
            int n = px.length;
            int ylen = 0;
            boolean[] used = new boolean[n];
            for (int i = 0; i < n; i++) {
                if (abs(py[i].x - X) * abs(py[i].x - X) <= best.res) {
                    used[i] = true;
                    ylen++;
                }
            }
            Point[] y = new Point[ylen];
            for (int i = 0, j = 0; i < n; i++) {
                if (used[i]) {
                    y[j++] = py[i];
                }
            }
            long min = Long.MAX_VALUE;
            int ii = -1, jj = -1;
            for (int i = 0; i < ylen; i++) {
                for (int j = i+1; j <= min(i+7, ylen-1); j++) {
                    long D = dist(y[i], y[j]);
                    if (min > D) {
                        min = D;
                        ii = i;
                        jj = j;
                    }
                }
            }
            if (min >= best.res) {
                return best;
            } else {
                return new Answer(y[ii], y[jj], min);
            }
        }
        
        void solve() throws IOException{
            int n = readInt();
            Point[] p = new Point[n];
            for (int i = 0; i < n; i++){
                int x = readInt();
                int y = readInt();
                int k = 1;
                if (x < 0 && y >= 0) k = 2;
                if (y < 0 && x >= 0) k = 3;
                if (x < 0 && y < 0) k = 4;
                x = abs(x);
                y = abs(y);
                p[i] = new Point(x, y, k, i);
            }
            Point[] x = new Point[n];
            Point[] y = new Point[n];
            for (int i = 0; i < n; i++){
                x[i] = new Point(p[i].x, p[i].y, p[i].k, i);
                y[i] = new Point(p[i].x, p[i].y, p[i].k, i);
            }
            Arrays.sort(x, new Comparator<Point>(){

                @Override
                public int compare(J.Point p1, J.Point p2) {
                    return (int) (p1.x - p2.x);
                }
                
            });
            Arrays.sort(y, new Comparator<Point>(){

                @Override
                public int compare(J.Point p1, J.Point p2) {
                    return (int) (p1.y - p2.y);
                }
                
            });
            Answer ans = go(x, y);
            out.print(ans.p.i+1 + " " + ans.p.k + " ");
            out.print(ans.q.i+1 + " " + (5 - ans.q.k));
        }              
        
}