Problem: You are given the set of vectors on the plane, each of them starting at the origin. Your task is to find a pair of vectors with the minimal non-oriented angle between them.

Non-oriented angle is non-negative value, minimal between clockwise and counterclockwise direction angles. Non-oriented angle is always between 0 and π. For example, opposite directions vectors have angle equals to π.

Input

First line of the input contains a single integer n (2 ≤ n ≤ 100 000) — the number of vectors.

The i-th of the following n lines contains two integers xi and yi (|x|, |y| ≤ 10 000, x2 + y2 > 0) — the coordinates of the i-th vector. Vectors are numbered from 1 to n in order of appearing in the input. It is guaranteed that no two vectors in the input share the same direction (but they still can have opposite directions).

Output

Print two integer numbers a and b (a ≠ b) — a pair of indices of vectors with the minimal non-oriented angle. You can print the numbers in any order. If there are many possible answers, print any.

Examples

Input

4
-1 0
0 -1
1 0
1 1


Output

3 4


Input

6
-1 0
0 -1
1 0
1 1
-4 -5
-4 -6


Output

6 5

Solution (in JAVA):

Solution:
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.PrintStream;
import java.io.BufferedInputStream;
import java.util.concurrent.Callable;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.math.BigDecimal;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.util.Comparator;
import java.util.Collections;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		BufferedInputStream in = new BufferedInputStream(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}

	static class TaskC {
		public void solve(int testNumber, BufferedInputStream _in, PrintWriter out) {

			InputReader in = new InputReader(_in);

			long startTime = System.currentTimeMillis();

			int nt = 1;

			Task t = new Task(1);
			t.readInput(in);
			t.call();
			t.writeOutput(out);


			in.close();
			System.err.println("Time: " + (System.currentTimeMillis() - startTime) + " miliseconds");
		}

	}

	static class Task implements Callable<Task> {
		int n;
		ArrayList<Point> lp = new ArrayList<>();
		int si = 0;
		int sj = 0;
		int testNumber;

		public void readInput(InputReader in) {
	/* read input here */
			n = in.nextInt();
			for (int i = 0; i < n; ++i) {
				Point p = new Point(in.nextInt(), in.nextInt());
				p.val = i + 1;
				lp.add(p);
			}

		}

		public Task call() {
	/* process main algorithm here */
			Point.sortByAngle(lp, new Point(0, 0));

			System.err.println();
			BigDecimal mn = BigDecimal.valueOf(10000);
			ArrayList<Pair<Integer, Integer>> epi2 = new ArrayList<>();
			ArrayList<Task.PP> lpi2 = new ArrayList<>();
			ArrayList<Task.PP> gpi2 = new ArrayList<>();
			for (int i = 0; i < n; ++i) {
				Point v1 = lp.get(i);
				Point v2 = lp.get((i + 1) % n);
				long temp = v1.opPow(v2);
				if (temp >= 0) {

					//return Math.atan2(Point._opPow(this, p), Point._opMul(this, p));
					long y = v1.opPow(v2);
					long x = v1.opMul(v2);

					if (x > 0) {
						lpi2.add(new Task.PP(new Fraction(y, x), v1.val, v2.val));
					} else if (x == 0) {
						epi2.add(new Pair<>(v1.val, v2.val));
					} else {
						gpi2.add(new Task.PP(new Fraction(y, x), v1.val, v2.val));
					}
				}


			}

			if (lpi2.size() > 0) {
				Collections.sort(lpi2);
				si = lpi2.get(0).si;
				sj = lpi2.get(0).sj;
			} else if (epi2.size() > 0) {
				si = epi2.get(0).first;
				sj = epi2.get(0).second;
			} else {
				Collections.sort(gpi2);
				//Collections.reverse(gpi2);
				si = gpi2.get(0).si;
				sj = gpi2.get(0).sj;
			}

//		for(int i = n - 1; i >= 0; --i) {
//			Point v1 = lp.get(i);
//			Point v2 = i > 0 ? lp.get(i - 1) : lp.get(n - 1);
//
//			long temp =v1.opMul(v2);
//			if(temp >= 0) {
//				double t = temp;
//				double cosa = t / v1.norm() / v2.norm();
//				if(cosa > mx) {
//					mx = cosa;
//					si = v1.val;
//					sj = v2.val;
//				}
//			}
//
//			temp =v2.opMul(v1);
//			if(temp >= 0) {
//				double t = temp;
//				double cosa = t / v1.norm() / v2.norm();
//				if(cosa > mx) {
//					mx = cosa;
//					si = v1.val;
//					sj = v2.val;
//				}
//			}
//		}

			return this;
		}

		public void writeOutput(PrintWriter out) {
			out.println(si + " " + sj);
		}

		Task(int testNumber) {
			this.testNumber = testNumber;
		}

		static class PP implements Comparable<Task.PP> {
			Fraction f;
			int si;
			int sj;

			public PP(Fraction f, int si, int sj) {
				this.f = f;
				this.si = si;
				this.sj = sj;
			}


			public int compareTo(Task.PP o) {
				return f.compareTo(o.f);
			}

		}

	}

	static class InputReader {
		public BufferedReader reader;
		public StringTokenizer tokenizer;

		public InputReader(BufferedInputStream stream) {
			reader = new BufferedReader(new InputStreamReader(stream), 32768);
			tokenizer = null;
		}

		public String next() {
			while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {
					tokenizer = new StringTokenizer(reader.readLine());
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return tokenizer.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public void close() {
			try {
				if (reader != null)
					reader.close();
			} catch (Exception ex) {
				throw new RuntimeException(ex);
			}
		}

	}

	static class Pair<T1 extends Comparable<T1>, T2 extends Comparable<T2>> implements Comparable<Pair<T1, T2>> {
		public T1 first;
		public T2 second;

		public Pair(T1 first, T2 second) {
			this.first = first;
			this.second = second;
		}


		public int compareTo(Pair<T1, T2> o) {
			int _c1 = first.compareTo(o.first);
			if (_c1 != 0)
				return _c1;
			return second.compareTo(o.second);
		}

		public String toString() {
			return first + " " + second;
		}


		public int hashCode() {
			return first.hashCode() ^ second.hashCode();
		}

	}

	static class Fraction implements Comparable<Fraction> {
		private long a;
		private long b;

		long gcd(long a, long b) {
			return b == 0 ? a : gcd(b, a % b);
		}

		public Fraction(long a, long b) {
			this.a = a;
			this.b = b;
			if (b == 0) throw new RuntimeException();
			reduce();
		}

		public void reduce() {
			long g = gcd(Math.abs(a), Math.abs(b));
			if (b < 0) g = -g;
			this.a /= g;
			this.b /= g;
		}


		public int compareTo(Fraction o) {
			return Long.valueOf(this.a * o.b).compareTo(o.a * this.b);
		}


		public String toString() {
			return +a + "/" + b;
		}


		public int hashCode() {
			return Long.hashCode(a) ^ Long.hashCode(b);
		}

		public boolean equals(Object obj) {
			if (obj instanceof Fraction) {
				return this.compareTo((Fraction) obj) == 0;
			}
			return false;
		}

	}

	static class Point implements Comparable<Point> {
		public long x;
		public long y;
		public int val;

		public Point(Point o) {
			this.x = o.x;
			this.y = o.y;

		}

		public Point(long x, long y) {
			super();

			this.x = x;
			this.y = y;
		}


		public int compareTo(Point o) {
			int t = Long.valueOf(y).compareTo(o.y);
			if (t != 0)
				return t;


			return Long.valueOf(x).compareTo(o.x);
		}

		public long opMul(Point b) {
			return Point._opMul(this, b);
		}

		public long opPow(Point b) {
			return Point._opPow(this, b);
		}

		public static long _opMul(Point lhs, Point rhs) {

			return ((lhs.x * rhs.x) + (lhs.y * rhs.y));
		}

		public static long _opPow(Point lhs, Point rhs) {
			return ((lhs.x * rhs.y) - (lhs.y * rhs.x));
		}

		public static long ccw(Point lhs, Point rhs) {
			return _opPow(rhs, lhs);
		}

		public static long ccw(Point lhs, Point rhs, Point origin) {

			return ccw(new Point((lhs.x - origin.x), (lhs.y - origin.y)), new Point((rhs.x - origin.x), (rhs.y - origin.y)));
		}

		public static void sortByAngle(ArrayList<Point> points, Point origin) {
			ArrayList<Point> l0 = new ArrayList<>();
			ArrayList<Point> l1 = new ArrayList<>();
			ArrayList<Point> l2 = new ArrayList<>();
			for (Point p : points) {
				if (origin.compareTo(p) == 0) {
					l0.add(p);
				} else if (p.compareTo(origin) > 0) {
					l1.add(p);
				} else {
					l2.add(p);
				}
			}

			final Comparator<Point> cmp = (Point lhs, Point rhs) -> Long.valueOf(Point.ccw(lhs, rhs, origin)).compareTo(0l);


			Collections.sort(l1, cmp);
			Collections.sort(l2, cmp);
			points.clear();
			points.addAll(l0);
			points.addAll(l1);
			points.addAll(l2);
		}


		public String toString() {
			return x + " " + y;
		}

	}
}