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 cf120j {
	static int n;
	public static void main(String[] args) throws Exception {
		FastScanner in = new FastScanner(new File("input.txt"));
		PrintWriter out = new PrintWriter("output.txt");
		n = 2;
		int N = in.nextInt();
		ArrayList<veca> vs = new ArrayList<veca>();
		ArrayList<veca> ts = new ArrayList<veca>();
		ArrayList<veca> rs = new ArrayList<veca>();
		
		for(int i=0; i<N; i++) {
			int x = in.nextInt();
			int y = in.nextInt();
			vs.add(new veca(new int[]{Math.abs(x),Math.abs(y)},i));
			ts.add(new veca(new int[]{Math.abs(x),Math.abs(y)},i));
			rs.add(new veca(new int[]{x,y},i));
		}
		KDTree kd = new KDTree(vs);
		int best = Integer.MAX_VALUE;
		veca a = null;
		veca b = null;
		for(veca v : ts) {
			veca tmp = kd.findBest(v);
			int rr = tmp.dist2(v);
			if(rr < best) {
				a = v;
				b = tmp;
				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));

		out.printf("%d %d %d %d%n", a.id+1,k1,b.id+1,k2);
	//	System.out.printf("%d %d %d %d%n", a.id+1,k1,b.id+1,k2);
		out.close();
	}
	static int getKValue(veca a, veca b)
	{
		if ((a.v[0] == b.v[0])&&(a.v[1] == b.v[1]))
			return 1;
		if ((a.v[0] != b.v[0])&&(a.v[1] == b.v[1]))
			return 2;
		if ((a.v[0] == b.v[0])&&(a.v[1] != b.v[1]))
			return 3;
		return 4;
	}
	static class KDTree {
		Node root;
		Random rand = new Random(System.currentTimeMillis());
		KDTree(ArrayList<veca> pts) {
			Collections.shuffle(pts);
			root = build(pts,0);
		}
		Node build(ArrayList<veca> pts, int depth) {
			if(pts.size()==0) return null;
			int pivot = rand.nextInt(pts.size());
			veca piv = pts.get(pivot);
			ArrayList<veca> left = new ArrayList<veca>();
			ArrayList<veca> right = new ArrayList<veca>();
			for(int i=0; i<pts.size(); i++)
				if(i != pivot)
					if(pts.get(i).compareTo(piv,depth%n) < 0)
						left.add(pts.get(i));
					else 
						right.add(pts.get(i));
			return new Node(pts.get(pivot), build(left,depth+1), build(right,depth+1));
		}
		veca findBest(veca v) {
			return root.find(v,0);
		}
		static class Node {
			veca loc;
			Node left,right;
			Node(veca v, Node l, Node r) {
				loc = v; left=l; right=r;
			}
			veca find(veca target, int depth) {
				veca best = null;
				if(target.id != loc.id) best = loc; 
				if(left == null && right == null) 
					return best;
				if(right == null)
					return min(best,left.find(target, depth+1),target);
				if(left == null)
					return min(best,right.find(target, depth+1),target);
				if(target.compareTo(loc, depth) < 0) {
					best = min(best,left.find(target, depth+1),target);			
					if(best == null || target.axisDist2(loc, depth) <= best.dist2(target)) 
						best = min(best,right.find(target, depth+1),target);
				}
				else {
					best = min(best,right.find(target, depth+1),target);
					if(best == null || target.axisDist2(loc, depth) <= best.dist2(target)) 
						best = min(best,left.find(target, depth+1),target);
				}
				return best;
			}
			veca min(veca a, veca b, veca tar) {
				if(a==null) return b;
				if(b==null) return a;
				return a.dist2(tar) < b.dist2(tar) ? a : b;
			}
		}
	}
	static class veca {
		int[] v;
		int id;
		veca(int[] vv, int ii) {
			v = vv;
			id=ii;
		}
		int dist2(veca rhs) {
			int ret = 0;
			for(int i=0; i<n; i++) 
				ret += (rhs.v[i]-v[i])*(rhs.v[i]-v[i]);
			return ret;
		}
		int axisDist2(veca rhs, int depth) {
			int ret = rhs.v[depth%n] - v[depth%n];
			return ret*ret;
		}
		veca invert() {
			return new veca(new int[]{-v[0],-v[1]},id);
		}
		int compareTo(veca rhs, int dim) {
			for(int i=0; i<n; i++) 
				if(v[(i+dim)%n] != rhs.v[(i+dim)%n])
					return v[(i+dim)%n] - rhs.v[(i+dim)%n];
			return 0;
		}
	}
	static class FastScanner {
		FileInputStream in;
		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;
			}
		}
	}
}