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.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Scanner;

public class J {                                //AC
    static class Point implements Comparable<Point> {
        int x, y, idx, k, k1;

        public Point(int xx, int yy, int i, int kk, int kk1) {
            x = xx;
            y = yy;
            idx = i;
            k = kk;
            k1 = kk1;
        }

        public int compareTo(Point z) {
            if (z.x < x || z.x == x && z.y < y)
                return 1;
            return -1;
        }
    }

    static Point[] ar;
    static double MinSoFar;
    static int r1, r2, k1, k2;

    public static Point[] getMin(int st, int end) {
        if (st == end)
            return new Point[] { ar[st] };
        if (end == st + 1) {
            double tmp = Math.sqrt((ar[st].x - ar[end].x)
                    * (ar[st].x - ar[end].x) + (ar[st].y - ar[end].y)
                    * (ar[st].y - ar[end].y));
            if (tmp < MinSoFar && ar[st].idx != ar[end].idx) {
                MinSoFar = tmp;
                r1 = ar[st].idx;
                r2 = ar[end].idx;
                k1 = ar[st].k;
                k2 = ar[end].k1;
            }
            if (ar[st].y > ar[end].y) {
                return new Point[] { ar[end], ar[st] };
            } else
                return new Point[] { ar[st], ar[end] };
        }
        int midIdx = st + (end - st) / 2;
        double midx = (ar[midIdx].x + ar[midIdx + 1].x) / 2.0;
        Point[] t1 = getMin(st, midIdx);
        Point[] t2 = getMin(midIdx + 1, end);
        Point[] tmp = new Point[end - st + 1];
        Point[] ret = new Point[end - st + 1];
        int stIdx = 0, stIdx2 = 0;
        int i = 0, j = 0;
        double stRange = midx - MinSoFar;
        double endRange = midx + MinSoFar;
        while (i < t1.length & j < t2.length) {
            if (t1[i].y < t2[j].y) {
                if (t1[i].x >= stRange)
                    tmp[stIdx++] = t1[i];
                ret[stIdx2++] = t1[i];
                i++;
            } else {
                if (t2[j].x <= endRange)
                    tmp[stIdx++] = t2[j];
                ret[stIdx2++] = t2[j];
                j++;
            }
        }
        while (i < t1.length) {
            if (t1[i].x >= stRange) {
                tmp[stIdx++] = t1[i];
            }
            ret[stIdx2++] = t1[i];
            i++;

        }
        while (j < t2.length) {
            if (t2[j].x <= endRange)
                tmp[stIdx++] = t2[j];
            ret[stIdx2++] = t2[j];
            j++;

        }
        for (int k = 0; k < stIdx; k++) {
            endRange = tmp[k].y + MinSoFar;
            stRange = tmp[k].y - MinSoFar;
            for (int l = k + 1; l < stIdx && tmp[l].y < endRange; l++) {
                double t = Math.sqrt((tmp[l].x - tmp[k].x)
                        * (tmp[l].x - tmp[k].x) + (tmp[l].y - tmp[k].y)
                        * (tmp[l].y - tmp[k].y));
                if (t < MinSoFar && tmp[l].idx != tmp[k].idx) {
                    MinSoFar = t;
                    r1 = tmp[l].idx;
                    r2 = tmp[k].idx;
                    k1 = tmp[l].k;
                    k2 = tmp[k].k1;
                }
            }
            for (int l = k - 1; l >= 0 && tmp[l].y > stRange; l--) {
                double t = Math.sqrt((tmp[l].x - tmp[k].x)
                        * (tmp[l].x - tmp[k].x) + (tmp[l].y - tmp[k].y)
                        * (tmp[l].y - tmp[k].y));
                if (t < MinSoFar && tmp[l].idx != tmp[k].idx) {
                    MinSoFar = t;
                    r1 = tmp[l].idx;
                    r2 = tmp[k].idx;
                    k1 = tmp[l].k;
                    k2 = tmp[k].k1;
                }
            }
        }
        return ret;
    }

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(new FileReader("input.txt"));
        FileWriter fw = new FileWriter("output.txt");
        ar = new Point[sc.nextInt() * 4];
        for (int i = 0; i < ar.length / 4; i++) {
            int tx = sc.nextInt();
            int ty = sc.nextInt();
            ar[i * 4] = new Point(tx, ty, i + 1, 1, 4);
            ar[i * 4 + 1] = new Point(-1 * tx, ty, i + 1, 2, 3);
            ar[i * 4 + 2] = new Point(tx, -1 * ty, i + 1, 3, 2);
            ar[i * 4 + 3] = new Point(-1 * tx, -1 * ty, i + 1, 4, 1);
        }
        Arrays.sort(ar);
        MinSoFar = Integer.MAX_VALUE;
        getMin(0, ar.length - 1);
        fw.write(r1 + " " + k1 + " " + r2 + " " + k2 + "\n");
        fw.flush();
    }
}