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 static java.lang.Math.*;
import static java.lang.System.currentTimeMillis;
import static java.lang.System.exit;
import static java.lang.System.arraycopy;
import static java.util.Arrays.sort;
import static java.util.Arrays.binarySearch;
import static java.util.Arrays.fill;
import java.util.*;
import java.io.*;

public class Main {

	public static void main(String[] args) throws IOException {
		try {
			if (new File("input.txt").exists())
				System.setIn(new FileInputStream("input.txt"));
		} catch (SecurityException e) {
		}
		new Thread(null, new Runnable() {
			public void run() {
				try {
					new Main().run();
				} catch (Throwable e) {
					e.printStackTrace();
					exit(999);
				}
			}
		}, "1", 1 << 23).start();
	}

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st = new StringTokenizer("");

	int Type[][] = {{1, 1}, {-1, 1}, {1, -1}, {-1, -1}};
	Point point[];
	
	int inf_dist = 20000 * 20000;
	
	Point a, b;
	int dist = inf_dist;
	
	
	//	[le, ri)
	int compute(int le, int ri){
		if(ri <= le + 1)
			return inf_dist;
		int mid = (le + ri) >> 1;
		sort_xy = true;
		sort(point, le, ri);
		
		compute(le, mid);
		compute(mid, ri);
		
		sort_xy = true;
		sort(point, le, ri);
		
		int sle = max(le, mid - 1);
		int nle = max(le, mid - 1);
		while(nle > le && sqr(point[nle - 1].x - point[sle].x) <= dist)
				nle--;
		int sri = mid;
		int nri = mid;
		while(nri < ri && sqr(point[nri].x - point[sri].x) <= dist)
				nri++;
		
		sort_xy = false;
		sort(point, nle, nri);
		for(int i = nle; i < nri; i++){
			for(int j = i - 1; j >= nle; j--){
				if(sqr(point[i].y - point[j].y) > dist)
					break;
				if(dist(i, j) < dist){
					dist = dist(i, j);
					a = point[i];
					b = point[j];
				}
			}
		}
		return dist;
	}
	int dist(int i, int j){
		return sqr(point[i].x - point[j].x) + sqr(point[i].y - point[j].y);
	}
	
	int sqr(int x){
		return x * x;
	}
	private void run() throws IOException {
		in = new BufferedReader(new FileReader("input.txt"));
		out = new PrintWriter("output.txt");
//		in = new BufferedReader(new InputStreamReader(System.in));
//		out = new PrintWriter(System.out);

		int n = nextInt();
		point = new Point[n];
		for(int i = 0; i < n; i++)
			point[i] = new Point(nextInt(), nextInt(), i);
		compute(0, n);
		b.invert();
		out.println((a.id + 1) + " " + (a.type + 1) + " " + (b.id + 1) + " " + (b.type + 1));
		in.close();
		out.close();
	}
	
	boolean sort_xy = false;
	
	class Point implements Comparable<Point>{
		int x, y;
		int type;
		int id;
		Point(int x, int y, int id){
			for(int i = 0; i < 4; i++)
				if(Type[i][0] * x >= 0 && Type[i][1] * y >= 0)
					type = i;
			this.x = x * Type[type][0];
			this.y = y * Type[type][1];
			this.id = id;
		}
		void invert(){
			for(int i = 0; i < 4; i++)
				if(Type[i][0] * Type[type][0] * x <= 0 && Type[i][1] * Type[type][1] * y <= 0){
					type = i;
					break;
				}
		}
		public int compareTo(Point p){
			if(sort_xy)
				return x != p.x ? x - p.x : y - p.y;
			else
				return y != p.y ? y - p.y : x - p.x;
				
		}
		public String toString(){
			return "" + (id + 1);
		}
	}
	String nextToken() throws IOException {
		while (!st.hasMoreTokens())
			st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}
	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}
	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}
	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}
	String nextLine() throws IOException {
		st = new StringTokenizer("");
		return in.readLine();
	}
	boolean EOF() throws IOException {
		while (!st.hasMoreTokens()) {
			String s = in.readLine();
			if (s == null)
				return true;
			st = new StringTokenizer(s);
		}
		return false;
	}
}