#include <set>
#include <map>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <cassert>
#include <climits>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <fstream>
#include <sstream>
#include <iostream>
#include <algorithm>

using namespace std;

#define LL long long
#define F first
#define S second
#define PB push_back
#define PF push front
#define MP make_pair
#define REP(x, n) for(int x=0; x<(n); ++x)
#define FOR(x, b, e) for(int x=b; x<=(e); ++x)
#define FORD(x, b, e) for(int x=b; x>=(e); x)
#define VAR(v,n) __typeof(n) v=(n)
#define FOREACH(i,c) for(VAR(i,(c).begin());i!=(c).end();++i)
#define MOD(x, n) ((x)%(n)+(n))%(n)
#define SZ(x) (int((x).size()))
#define ALL(x) ((x).begin()),((x).end())
#define SORT(v) sort((v).begin(),(v).end())
#define UNIQUE(v) SORT(v),(v).erase(unique((v).begin(),(v).end()),(v).end())
LL GCD( LL a , LL b ) { while( b ) b ^= a ^= b ^= a %= b ; return a ; }
LL LCM( LL a , LL b ) { return a * ( b / GCD( a , b ) ) ; }

typedef vector<int>    VI;
typedef vector<VI>     VVI;
typedef vector<LL>     VLL;
typedef vector<bool>   VB;
typedef vector<double> VD;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef vector<PII>    VPII;
typedef pair<LL, LL>   PLL;
typedef vector<PLL>    VPLL;

const double EPS = 10e-7;
const double INF = (1LL << 62);

struct Point {
    double x;
    double y;
};

Point xy[100];

Point circumcircle(Point &A, Point &B, Point &C) {
    double x = (A.x*A.x+A.y*A.y)*(B.y-C.y)+(B.x*B.x+B.y*B.y)*(C.y-A.y)+(C.x*C.x+C.y*C.y)*(A.y-B.y);
    double y = (A.x*A.x+A.y*A.y)*(C.x-B.x)+(B.x*B.x+B.y*B.y)*(A.x-C.x)+(C.x*C.x+C.y*C.y)*(B.x-A.x);
    double d = 2.0*(A.x*(B.y-C.y)+B.x*(C.y-A.y)+C.x*(A.y-B.y));
    x /= d; y /= d;

    Point p; p.x = x; p.y = y;
    return p;
}

double sign(Point &p1, Point &p2, Point &p3) {
    return (p1.x-p3.x)*(p2.y-p3.y)-(p2.x-p3.x)*(p1.y-p3.y);
}

bool inside(Point &v1, Point &v2, Point &v3, Point &p) {
    double s1, s2, s3;
    s1 = sign(p, v1, v2);
    s2 = sign(p, v2, v3);
    s3 = sign(p, v3, v1);

    return (s1 > EPS && s2 > EPS && s3 > EPS) || (s1 < -EPS && s2 < -EPS && s3 < -EPS);
}

double dist(Point A, Point B) {
    return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
}

Point median(Point A, Point B) {
    Point m;
    m.x = (A.x+B.x)/2;
    m.y = (A.y+B.y)/2;
    return m;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    int N;
    cin >> N;

    REP(i, N) {
        cin >> xy[i].x >> xy[i].y;
    }

    double maxDist = -1;
    REP(i, N) {
        REP(j, i) {
            REP(k, j) {
                Point c = circumcircle(xy[i], xy[j], xy[k]);
                bool in = inside(xy[i], xy[j], xy[k], c) && abs(c.x) < 1e4 && abs(c.y) < 1e4;

                // check if there is another point strictly inside the circumference
                bool ok = true;
                REP(kk, N) {
                    if(kk != i && kk != j && kk != k && dist(xy[i], c) > dist(c, xy[kk])) {
                        ok = false;
                        break;
                    }
                }
                if(ok && in) {
                    // no point strictly inside
                    maxDist = max(maxDist, dist(xy[i], c));
                } else if(ok && !in) {
                    Point pts[3] = {xy[i], xy[j], xy[k]};
                    bool mid = false;
                    REP(kk, 3) {
                        mid |= (sqrt(dist(median(pts[kk], pts[(kk+1)%3]), c)) < EPS);
                    }

                    if(mid) {
                        REP(kk, N) {
                            if(kk != i && kk != j && kk != k && abs(dist(xy[i], c)-dist(c, xy[kk])) < EPS) {
                                maxDist = max(maxDist, dist(xy[i], c));
                                break;
                            }
                        }
                    }
                }
            }
        }
    }

    if(maxDist != -1)
        cout << sqrt(maxDist) << endl;
    else
        cout << -1 << endl;

    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <utility>
#include <numeric>
#include <algorithm>
#include <bitset>
#include <complex>
#include <unordered_set>
#include <unordered_map>

using namespace std;

typedef unsigned uint;
typedef long long Int;
typedef vector<int> vint;
typedef pair<int,int> pint;
#define mp make_pair

template<typename T> void pv(T a, T b) { for (T i = a; i != b; ++i) cout << *i << " "; cout << endl; }
template<typename T> void chmin(T &t, const T &f) { if (t > f) t = f; }
template<typename T> void chmax(T &t, const T &f) { if (t < f) t = f; }
int in() { int x; scanf("%d", &x); return x; }

double EPS = 1e-10;
const double INF = 1e+10;
const double PI = acos(-1.0);
int sig(double r) { return (r < -EPS) ? -1 : (r > +EPS) ? +1 : 0; }

struct Pt {
	double x, y;
	Pt() {}
	Pt(double x, double y) : x(x), y(y) {}
	Pt operator+(const Pt &a) const { return Pt(x + a.x, y + a.y); }
	Pt operator-(const Pt &a) const { return Pt(x - a.x, y - a.y); }
	Pt operator*(const Pt &a) const { return Pt(x * a.x - y * a.y, x * a.y + y * a.x); }
	Pt operator-() const { return Pt(-x, -y); }
	Pt operator*(const double &k) const { return Pt(x * k, y * k); }
	Pt operator/(const double &k) const { return Pt(x / k, y / k); }
	double abs() const { return sqrt(x * x + y * y); }
	double abs2() const { return x * x + y * y; }
	double arg() const { return atan2(y, x); }
	double dot(const Pt &a) const { return x * a.x + y * a.y; }
	double det(const Pt &a) const { return x * a.y - y * a.x; }
	friend ostream &operator<<(ostream &os, const Pt &a) { os << "(" << a.x << ", " << a.y << ")"; return os; }
};
double tri(const Pt &a, const Pt &b, const Pt &c) { return (b - a).det(c - a); }

Pt circumcenter(const Pt &a, const Pt &b, const Pt &c) {
	const Pt bc = c - b, ca = a - c, ab = b - a;
	return (b + c - bc * Pt(0, 1) * ca.dot(ab) / ca.det(ab)) / 2;
}

int N;
Pt P[110];

bool check(const Pt &p, double r) {
	for (int i = 0; i < N; ++i) {
		if (sig((P[i] - p).abs() - r) < 0) {
			return false;
		}
	}
	return true;
}

int main() {

	for (; ~scanf("%d", &N); ) {
		for (int i = 0; i < N; ++i) {
			P[i].x = in();
			P[i].y = in();
		}
		double ans = -1.0;
		for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) for (int k = 0; k < N; ++k) {
			if (sig(tri(P[i], P[j], P[k])) > 0) {
				const int sdi = sig((P[j] - P[i]).dot(P[k] - P[i]));
				const int sdj = sig((P[k] - P[j]).dot(P[i] - P[j]));
				const int sdk = sig((P[i] - P[k]).dot(P[j] - P[k]));
				bool ok = true;
				if (sdi > 0 && sdj > 0 && sdk > 0) {
					ok = true;
				} else if (sdi > 0 && sdj == 0 && sdk > 0) {
					for (int l = 0; l < N; ++l) if (sig((P[i] - P[j] + P[k] - P[l]).abs()) == 0) {
						ok = true;
					}
				}
				if (ok) {
					const Pt o = circumcenter(P[i], P[j], P[k]);
					const double r = (P[i] - o).abs();
					if (check(o, r)) {
						chmax(ans, r);
					}
				}
			}
		}
		printf("%.10f\n", ans);
	}

	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <utility>
#include <numeric>
#include <algorithm>
#include <bitset>
#include <complex>
#include <unordered_set>
#include <unordered_map>

using namespace std;

typedef unsigned uint;
typedef long long Int;
typedef vector<int> vint;
typedef pair<int,int> pint;
#define mp make_pair

template<typename T> void pv(T a, T b) { for (T i = a; i != b; ++i) cout << *i << " "; cout << endl; }
template<typename T> void chmin(T &t, const T &f) { if (t > f) t = f; }
template<typename T> void chmax(T &t, const T &f) { if (t < f) t = f; }
int in() { int x; scanf("%d", &x); return x; }

double EPS = 1e-10;
const double INF = 1e+10;
const double PI = acos(-1.0);
int sig(double r) { return (r < -EPS) ? -1 : (r > +EPS) ? +1 : 0; }

struct Pt {
	double x, y;
	Pt() {}
	Pt(double x, double y) : x(x), y(y) {}
	Pt operator+(const Pt &a) const { return Pt(x + a.x, y + a.y); }
	Pt operator-(const Pt &a) const { return Pt(x - a.x, y - a.y); }
	Pt operator*(const Pt &a) const { return Pt(x * a.x - y * a.y, x * a.y + y * a.x); }
	Pt operator-() const { return Pt(-x, -y); }
	Pt operator*(const double &k) const { return Pt(x * k, y * k); }
	Pt operator/(const double &k) const { return Pt(x / k, y / k); }
	double abs() const { return sqrt(x * x + y * y); }
	double abs2() const { return x * x + y * y; }
	double arg() const { return atan2(y, x); }
	double dot(const Pt &a) const { return x * a.x + y * a.y; }
	double det(const Pt &a) const { return x * a.y - y * a.x; }
	friend ostream &operator<<(ostream &os, const Pt &a) { os << "(" << a.x << ", " << a.y << ")"; return os; }
};
double tri(const Pt &a, const Pt &b, const Pt &c) { return (b - a).det(c - a); }

Pt circumcenter(const Pt &a, const Pt &b, const Pt &c) {
	const Pt bc = c - b, ca = a - c, ab = b - a;
	return (b + c - bc * Pt(0, 1) * ca.dot(ab) / ca.det(ab)) / 2;
}

int N;
Pt P[110];

bool check(const Pt &p, double r) {
	for (int i = 0; i < N; ++i) {
		if (sig((P[i] - p).abs() - r) < 0) {
			return false;
		}
	}
	return true;
}

int main() {

	for (; ~scanf("%d", &N); ) {
		for (int i = 0; i < N; ++i) {
			P[i].x = in();
			P[i].y = in();
		}
		double ans = -1.0;
		for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) for (int k = 0; k < N; ++k) {
			if (sig(tri(P[i], P[j], P[k])) > 0) {
				const int sdi = sig((P[j] - P[i]).dot(P[k] - P[i]));
				const int sdj = sig((P[k] - P[j]).dot(P[i] - P[j]));
				const int sdk = sig((P[i] - P[k]).dot(P[j] - P[k]));
				bool ok = false;
				if (sdi > 0 && sdj > 0 && sdk > 0) {
					ok = true;
				} else if (sdi > 0 && sdj == 0 && sdk > 0) {
					for (int l = 0; l < N; ++l) if (sig((P[i] - P[j] + P[k] - P[l]).abs()) == 0) {
						ok = true;
					}
				}
				if (ok) {
					const Pt o = circumcenter(P[i], P[j], P[k]);
					const double r = (P[i] - o).abs();
					if (check(o, r)) {
						chmax(ans, r);
					}
				}
			}
		}
		printf("%.10f\n", ans);
	}

	return 0;
}


import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.io.InputStream;
import java.io.BufferedReader;
import java.util.List;
import java.util.Collections;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.StringTokenizer;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author AlexFetisov
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(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, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            Point[] p = new Point[n];
            for (int i = 0; i < n; ++i) {
                p[i] = new Point(in);
            }
            List<Double> allRes = new ArrayList<Double>();
            for (int i = 0; i < n; ++i) {
                for (int j = i + 1; j < n; ++j) {
                    for (int k = j + 1; k < n; ++k) {
                        double t = testTriangle(p[i], p[j], p[k], p);
                        if (t < 1e99) {
                            allRes.add(t);
                        }
                    }
                }
            }
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) {
                    for (int k = 0; k < n; ++k) {
                        if (i == j || i == k || j == k) continue;
                        double t = testSquare(p[i], p[j], p[k], p);
                        if (t < 1e99) {
                            allRes.add(t);
                        }
                    }
                }
            }

            Collections.sort(allRes);
            if (allRes.size() == 0) {
                out.println(-1);
                return;
            }
            out.println(allRes.get(allRes.size() - 1));
        }

        private double testSquare(Point A, Point B, Point C, Point[] p) {
            Point D;
            for (int i = 0; i < p.length; ++i) {
                D = p[i];
                if (checkSquare(A, B, C, D)) {
                    Point mAB = A.add(B).div(2);
                    Point mAD = A.add(D).div(2);
                    Line l = new Line(A, B).perpendicular(mAB);
                    Line l2 = new Line(C, D).perpendicular(mAD);
                    Point P = l.intersect(l2);
                    if (P == null) return 1e100;

                    double res = 1e100;
                    for (Point pp : p) {
                        res = Math.min(res, pp.distanceTo(P));
                    }
                    return res;
                }
            }
            return 1e100;
        }

        private boolean checkSquare(Point A, Point B, Point C, Point D) {
            boolean ok = DoubleUtils.compareTo(A.distanceTo(B), B.distanceTo(C)) == 0;
            ok &= DoubleUtils.compareTo(A.distanceTo(B), C.distanceTo(D)) == 0;
            ok &= DoubleUtils.compareTo(A.distanceTo(B), A.distanceTo(D)) == 0;
            if (!ok) return false;

            Point v1 = B.sub(A);
            Point v2 = D.sub(A);
            return DoubleUtils.compareTo(v1.dotProduct(v2), 0) == 0;
        }

        private double testTriangle(Point A, Point B, Point C, Point[] p) {
            Point mAB = A.add(B).div(2);
            Point mBC = C.add(B).div(2);
            Line l = new Line(A, B).perpendicular(mAB);
            Line l2 = new Line(C, B).perpendicular(mBC);
            Point P = l.intersect(l2);
            if (P == null) return 1e100;

            if (DoubleUtils.compareTo(GeometryUtils.triangleSquare(A, B, C),
                    GeometryUtils.triangleSquare(A, B, P) + GeometryUtils.triangleSquare(A, P, C) + GeometryUtils.triangleSquare(P, B, C)) == 0) {
                double res = 1e100;
                for (Point pp : p) {
                    res = Math.min(res, pp.distanceTo(P));
                }
                return res;
            }
            return 1e100;
        }

    }

    static class Point implements Comparable<Point> {
        public double x;
        public double y;

        public Point(double x, double y) {
            this.x = x;
            this.y = y;
        }

        public Point() {
            this.x = 0;
            this.y = 0;
        }

        public Point(InputReader in) {
            this.x = in.nextDouble();
            this.y = in.nextDouble();
        }

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

        public boolean equals(Object o) {
            Point p = (Point) o;
            return DoubleUtils.compareTo(x, p.x) == 0 && DoubleUtils.compareTo(y, p.y) == 0;
        }

        public int hashCode() {
            int result;
            long temp;
            temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
            result = (int) (temp ^ (temp >>> 32));
            temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
            result = 31 * result + (int) (temp ^ (temp >>> 32));
            return result;
        }

        public Point add(Point p) {
            return new Point(x + p.x, y + p.y);
        }

        public Point sub(Point p) {
            return new Point(x - p.x, y - p.y);
        }

        public Point div(double k) {
            return new Point(x / k, y / k);
        }

        public double dotProduct(Point p) {
            return x * p.x + y * p.y;
        }

        public double crossProduct(Point p) {
            return x * p.y - y * p.x;
        }

        public double length() {
            return DoubleUtils.sqrt(dotProduct(this));
        }

        public double distanceTo(Point p) {
            return sub(p).length();
        }

        public int compareTo(Point o) {
            int temp = DoubleUtils.compareTo(x, o.x);
            if (temp == 0) {
                return DoubleUtils.compareTo(y, o.y);
            }
            return temp;
        }

    }

    static class GeometryUtils {
        public static double triangleSquare(Point A, Point B, Point C) {
            return Math.abs(B.sub(A).crossProduct(C.sub(A))) / 2.;
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer stt;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream));
        }

        public String nextLine() {
            try {
                return reader.readLine();
            } catch (IOException e) {
                return null;
            }
        }

        public String nextString() {
            while (stt == null || !stt.hasMoreTokens()) {
                stt = new StringTokenizer(nextLine());
            }
            return stt.nextToken();
        }

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

        public double nextDouble() {
            return Double.parseDouble(nextString());
        }

    }

    static class Line {
        public final double a;
        public final double b;
        public final double c;
        public Point p1;
        public Point p2;
        boolean hasPoints;

        public Line(Point p, double angle) {
            a = Math.sin(angle);
            b = -Math.cos(angle);
            c = -p.x * a - p.y * b;
            p1 = p2 = null;
            hasPoints = false;
        }

        public Line(double a, double b, double c) {
            double h = DoubleUtils.hypot(a, b);
            this.a = a / h;
            this.b = b / h;
            this.c = c / h;
            hasPoints = false;
        }

        public Line(Point p1, Point p2) {
            double a = p2.y - p1.y;
            double b = p1.x - p2.x;
            double c = -(p1.x * a + p1.y * b);
            double h = DoubleUtils.hypot(a, b);
            this.a = a / h;
            this.b = b / h;
            this.c = c / h;
            hasPoints = true;
        }

        public Point intersect(Line other) {
            if (parallel(other)) {
                return null;
            }
            double determinant = b * other.a - a * other.b;
            double x = (c * other.b - b * other.c) / determinant;
            double y = (a * other.c - c * other.a) / determinant;
            return new Point(x, y);
        }

        public boolean parallel(Line other) {
            return DoubleUtils.compareTo(Math.abs(a * other.b - b * other.a), 0) == 0;
        }

        public Line perpendicular(Point point) {
            return new Line(-b, a, b * point.x - a * point.y);
        }

        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Line line = (Line) o;

            if (!parallel(line)) return false;
            if (Math.abs(a * line.c - c * line.a) > DoubleUtils.EPS || Math.abs(b * line.c - c * line.b) > DoubleUtils.EPS)
                return false;

            return true;
        }

    }

    static class DoubleUtils {
        public static final double EPS = 1e-9;

        public static double sqr(double x) {
            return x * x;
        }

        public static int compareTo(double a, double b) {
            if (doubleEqual(a, b)) {
                return 0;
            }
            if (a < b) {
                return -1;
            }
            return 1;
        }

        private static boolean doubleEqual(double a, double b) {
            return Math.abs(a - b) < EPS;
        }

        public static double sqrt(double a) {
            if (compareTo(a, 0) < 0) {
                System.exit(1);
            }
            if (a < 0) return 0;
            return Math.sqrt(a);
        }

        public static double hypot(double a, double b) {
            return sqrt(sqr(a) + sqr(b));
        }

    }
}


import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.io.InputStream;
import java.io.BufferedReader;
import java.util.List;
import java.util.Collections;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.StringTokenizer;

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

    static class TaskC {
        double[][] dsts;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            Point[] p = new Point[n];
            dsts = new double[n][n];
            for (int i = 0; i < n; ++i) {
                p[i] = new Point(in);
            }
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) {
                    dsts[i][j] = p[i].distanceTo(p[j]);
                }
            }
            List<Double> allRes = new ArrayList<Double>();
            for (int i = 0; i < n; ++i) {
                for (int j = i + 1; j < n; ++j) {
                    for (int k = j + 1; k < n; ++k) {
                        double t = testTriangle(p[i], p[j], p[k], p);
                        if (t < 1e99) {
                            allRes.add(t);
                        }
                    }
                }
            }
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) {
                    for (int k = 0; k < n; ++k) {
                        if (i == j || i == k || j == k) continue;
                        double t = testSquare(p[i], p[j], p[k], p, i, j, k);
                        if (t < 1e99) {
                            allRes.add(t);
                        }
                    }
                }
            }

            Collections.sort(allRes);
            if (allRes.size() == 0) {
                out.println(-1);
                return;
            }
            double r = allRes.get(allRes.size() - 1);
            if (DoubleUtils.compareTo(r, 0) == 0) {
                out.println(-1);
                return;
            }
            out.println(allRes.get(allRes.size() - 1));
        }

        private double testSquare(Point A, Point B, Point C, Point[] p, int i1, int i2, int i3) {
            Point D;
            for (int i = 0; i < p.length; ++i) {
                D = p[i];
                if (i == i1 || i == i2 || i == i3) continue;
                if (checkSquare(A, B, C, D, i1, i2, i3, i)) {
                    Point mAB = A.add(B).div(2);
                    Point mAD = A.add(D).div(2);
                    Line l = new Line(A, B).perpendicular(mAB);
                    Line l2 = new Line(A, D).perpendicular(mAD);
                    Point P = l.intersect(l2);
                    if (P == null) return 1e100;

                    double res = 1e100;
                    for (Point pp : p) {
                        res = Math.min(res, pp.distanceTo(P));
                    }
                    return res;
                }
            }
            return 1e100;
        }

        private boolean checkSquare(Point A, Point B, Point C, Point D, int i1, int i2, int i3, int i4) {
            boolean ok = DoubleUtils.compareTo(dsts[i1][i2], dsts[i2][i3]) == 0;
            ok &= DoubleUtils.compareTo(dsts[i1][i2], dsts[i3][i4]) == 0;
            ok &= DoubleUtils.compareTo(dsts[i1][i2], dsts[i1][i4]) == 0;
            if (!ok) return false;
            Point v1 = B.sub(A);
            Point v2 = D.sub(A);
            return DoubleUtils.compareTo(v1.dotProduct(v2), 0) == 0;
        }

        private double testTriangle(Point A, Point B, Point C, Point[] p) {
            Point mAB = A.add(B).div(2);
            Point mBC = C.add(B).div(2);
            Line l = new Line(A, B).perpendicular(mAB);
            Line l2 = new Line(C, B).perpendicular(mBC);
            Point P = l.intersect(l2);
            if (P == null) return 1e100;

            if (DoubleUtils.compareTo(GeometryUtils.triangleSquare(A, B, C),
                    GeometryUtils.triangleSquare(A, B, P) + GeometryUtils.triangleSquare(A, P, C) + GeometryUtils.triangleSquare(P, B, C)) == 0) {
                if (DoubleUtils.compareTo(GeometryUtils.triangleSquare(A, B, P), 0) == 0 ||
                        DoubleUtils.compareTo(GeometryUtils.triangleSquare(A, P, C), 0) == 0 ||
                        DoubleUtils.compareTo(GeometryUtils.triangleSquare(P, B, C), 0) == 0) {
                    return 1e100;
                }
                double res = 1e100;
                for (Point pp : p) {
                    res = Math.min(res, pp.distanceTo(P));
                }
                return res;
            }
            return 1e100;
        }

    }

    static class Point implements Comparable<Point> {
        public double x;
        public double y;

        public Point(double x, double y) {
            this.x = x;
            this.y = y;
        }

        public Point() {
            this.x = 0;
            this.y = 0;
        }

        public Point(InputReader in) {
            this.x = in.nextDouble();
            this.y = in.nextDouble();
        }

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

        public boolean equals(Object o) {
            Point p = (Point) o;
            return DoubleUtils.compareTo(x, p.x) == 0 && DoubleUtils.compareTo(y, p.y) == 0;
        }

        public int hashCode() {
            int result;
            long temp;
            temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
            result = (int) (temp ^ (temp >>> 32));
            temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
            result = 31 * result + (int) (temp ^ (temp >>> 32));
            return result;
        }

        public Point add(Point p) {
            return new Point(x + p.x, y + p.y);
        }

        public Point sub(Point p) {
            return new Point(x - p.x, y - p.y);
        }

        public Point div(double k) {
            return new Point(x / k, y / k);
        }

        public double dotProduct(Point p) {
            return x * p.x + y * p.y;
        }

        public double crossProduct(Point p) {
            return x * p.y - y * p.x;
        }

        public double length() {
            return DoubleUtils.sqrt(dotProduct(this));
        }

        public double distanceTo(Point p) {
            return sub(p).length();
        }

        public int compareTo(Point o) {
            int temp = DoubleUtils.compareTo(x, o.x);
            if (temp == 0) {
                return DoubleUtils.compareTo(y, o.y);
            }
            return temp;
        }

    }

    static class GeometryUtils {
        public static double triangleSquare(Point A, Point B, Point C) {
            return Math.abs(B.sub(A).crossProduct(C.sub(A))) / 2.;
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer stt;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream));
        }

        public String nextLine() {
            try {
                return reader.readLine();
            } catch (IOException e) {
                return null;
            }
        }

        public String nextString() {
            while (stt == null || !stt.hasMoreTokens()) {
                stt = new StringTokenizer(nextLine());
            }
            return stt.nextToken();
        }

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

        public double nextDouble() {
            return Double.parseDouble(nextString());
        }

    }

    static class Line {
        public final double a;
        public final double b;
        public final double c;
        public Point p1;
        public Point p2;
        boolean hasPoints;

        public Line(Point p, double angle) {
            a = Math.sin(angle);
            b = -Math.cos(angle);
            c = -p.x * a - p.y * b;
            p1 = p2 = null;
            hasPoints = false;
        }

        public Line(double a, double b, double c) {
            double h = DoubleUtils.hypot(a, b);
            this.a = a / h;
            this.b = b / h;
            this.c = c / h;
            hasPoints = false;
        }

        public Line(Point p1, Point p2) {
            double a = p2.y - p1.y;
            double b = p1.x - p2.x;
            double c = -(p1.x * a + p1.y * b);
            double h = DoubleUtils.hypot(a, b);
            this.a = a / h;
            this.b = b / h;
            this.c = c / h;
            hasPoints = true;
        }

        public Point intersect(Line other) {
            if (parallel(other)) {
                return null;
            }
            double determinant = b * other.a - a * other.b;
            double x = (c * other.b - b * other.c) / determinant;
            double y = (a * other.c - c * other.a) / determinant;
            return new Point(x, y);
        }

        public boolean parallel(Line other) {
            return DoubleUtils.compareTo(Math.abs(a * other.b - b * other.a), 0) == 0;
        }

        public Line perpendicular(Point point) {
            return new Line(-b, a, b * point.x - a * point.y);
        }

        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Line line = (Line) o;

            if (!parallel(line)) return false;
            if (Math.abs(a * line.c - c * line.a) > DoubleUtils.EPS || Math.abs(b * line.c - c * line.b) > DoubleUtils.EPS)
                return false;

            return true;
        }

    }

    static class DoubleUtils {
        public static final double EPS = 1e-9;

        public static double sqr(double x) {
            return x * x;
        }

        public static int compareTo(double a, double b) {
            if (doubleEqual(a, b)) {
                return 0;
            }
            if (a < b) {
                return -1;
            }
            return 1;
        }

        private static boolean doubleEqual(double a, double b) {
            return Math.abs(a - b) < EPS;
        }

        public static double sqrt(double a) {
            if (compareTo(a, 0) < 0) {
                System.exit(1);
            }
            if (a < 0) return 0;
            return Math.sqrt(a);
        }

        public static double hypot(double a, double b) {
            return sqrt(sqr(a) + sqr(b));
        }

    }
}


import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.util.List;
import java.util.StringTokenizer;
import java.io.InputStreamReader;
import java.io.IOException;

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

    static class TaskC {
        private Point[] p;
        double[][][] triSquare;
        Point[][] mids;
        double[][] dsts;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            p = new Point[n];
            dsts = new double[n][n];
            triSquare = new double[n][n][n];
            mids = new Point[n][n];

            for (int i = 0; i < n; ++i) {
                p[i] = new Point(in);
            }
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) {
                    dsts[i][j] = p[i].distanceTo(p[j]);
                    mids[i][j] = p[i].add(p[j]).div(2);
                    for (int k = 0; k < n; ++k) {
                        triSquare[i][j][k] = GeometryUtils.triangleSquare(p[i], p[j], p[k]);
                    }
                }
            }
            List<Double> allRes = new ArrayList<Double>();
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) {
                    for (int k = 0; k < n; ++k) {
                        if (i < j && j < k) {
                            double t = testTriangle(i, j, k);
                            if (t < 1e99) {
                                allRes.add(t);
                            }
                        }
                        if (i == j || i == k || j == k) continue;
                        double t = testSquare(i, j, k);
                        if (t < 1e99) {
                            allRes.add(t);
                        }
                    }
                }
            }

            if (allRes.size() == 0) {
                out.println(-1);
                return;
            }
            double max = 0;
            for (double x : allRes) {
                max = Math.max(x, max);
            }
            double r = max;
            if (DoubleUtils.compareTo(r, 0) == 0) {
                out.println(-1);
                return;
            }
            out.println(max);
        }

        private double testSquare(int i1, int i2, int i3) {
            for (int i = 0; i < p.length; ++i) {
                if (i == i1 || i == i2 || i == i3) continue;
                if (checkSquare(i1, i2, i3, i)) {
                    Line l = new Line(p[i1], p[i2]).perpendicular(mids[i1][i2]);
                    Line l2 = new Line(p[i1], p[i]).perpendicular(mids[i1][i]);
                    Point P = l.intersect(l2);
                    if (P == null) return 1e100;
                    double res = 1e100;
                    for (Point pp : p) {
                        res = Math.min(res, pp.distanceTo(P));
                    }
                    return res;
                }
            }
            return 1e100;
        }

        private boolean checkSquare(int i1, int i2, int i3, int i4) {
            boolean ok = DoubleUtils.compareTo(dsts[i1][i2], dsts[i2][i3]) == 0;
            ok &= DoubleUtils.compareTo(dsts[i1][i2], dsts[i3][i4]) == 0;
            ok &= DoubleUtils.compareTo(dsts[i1][i2], dsts[i1][i4]) == 0;
            if (!ok) return false;
            Point v1 = p[i2].sub(p[i1]);
            Point v2 = p[i4].sub(p[i1]);
            return DoubleUtils.compareTo(v1.dotProduct(v2), 0) == 0;
        }

        private double testTriangle(int i1, int i2, int i3) {
            Line l = new Line(p[i1], p[i2]).perpendicular(mids[i1][i2]);
            Line l2 = new Line(p[i2], p[i3]).perpendicular(mids[i2][i3]);
            Point P = l.intersect(l2);
            if (P == null) return 1e100;

            double S1 = GeometryUtils.triangleSquare(p[i1], p[i2], P);
            double S2 = GeometryUtils.triangleSquare(p[i1], P, p[i3]);
            double S3 = GeometryUtils.triangleSquare(P, p[i2], p[i3]);
            if (DoubleUtils.compareTo(triSquare[i1][i2][i3], S1 + S2 + S3) == 0) {
                if (DoubleUtils.compareTo(S1, 0) == 0 || DoubleUtils.compareTo(S2, 0) == 0 || DoubleUtils.compareTo(S3, 0) == 0) {
                    return 1e100;
                }
                double res = 1e100;
                for (Point pp : p) {
                    res = Math.min(res, pp.distanceTo(P));
                }
                return res;
            }
            return 1e100;
        }

    }

    static class Point implements Comparable<Point> {
        public double x;
        public double y;

        public Point(double x, double y) {
            this.x = x;
            this.y = y;
        }

        public Point() {
            this.x = 0;
            this.y = 0;
        }

        public Point(InputReader in) {
            this.x = in.nextDouble();
            this.y = in.nextDouble();
        }

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

        public boolean equals(Object o) {
            Point p = (Point) o;
            return DoubleUtils.compareTo(x, p.x) == 0 && DoubleUtils.compareTo(y, p.y) == 0;
        }

        public int hashCode() {
            int result;
            long temp;
            temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
            result = (int) (temp ^ (temp >>> 32));
            temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
            result = 31 * result + (int) (temp ^ (temp >>> 32));
            return result;
        }

        public Point add(Point p) {
            return new Point(x + p.x, y + p.y);
        }

        public Point sub(Point p) {
            return new Point(x - p.x, y - p.y);
        }

        public Point div(double k) {
            return new Point(x / k, y / k);
        }

        public double dotProduct(Point p) {
            return x * p.x + y * p.y;
        }

        public double crossProduct(Point p) {
            return x * p.y - y * p.x;
        }

        public double length() {
            return DoubleUtils.sqrt(dotProduct(this));
        }

        public double distanceTo(Point p) {
            return sub(p).length();
        }

        public int compareTo(Point o) {
            int temp = DoubleUtils.compareTo(x, o.x);
            if (temp == 0) {
                return DoubleUtils.compareTo(y, o.y);
            }
            return temp;
        }

    }

    static class GeometryUtils {
        public static double triangleSquare(Point A, Point B, Point C) {
            return Math.abs(B.sub(A).crossProduct(C.sub(A))) / 2.;
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer stt;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream));
        }

        public String nextLine() {
            try {
                return reader.readLine();
            } catch (IOException e) {
                return null;
            }
        }

        public String nextString() {
            while (stt == null || !stt.hasMoreTokens()) {
                stt = new StringTokenizer(nextLine());
            }
            return stt.nextToken();
        }

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

        public double nextDouble() {
            return Double.parseDouble(nextString());
        }

    }

    static class Line {
        public final double a;
        public final double b;
        public final double c;
        public Point p1;
        public Point p2;
        boolean hasPoints;

        public Line(Point p, double angle) {
            a = Math.sin(angle);
            b = -Math.cos(angle);
            c = -p.x * a - p.y * b;
            p1 = p2 = null;
            hasPoints = false;
        }

        public Line(double a, double b, double c) {
            double h = DoubleUtils.hypot(a, b);
            this.a = a / h;
            this.b = b / h;
            this.c = c / h;
            hasPoints = false;
        }

        public Line(Point p1, Point p2) {
            double a = p2.y - p1.y;
            double b = p1.x - p2.x;
            double c = -(p1.x * a + p1.y * b);
            double h = DoubleUtils.hypot(a, b);
            this.a = a / h;
            this.b = b / h;
            this.c = c / h;
            hasPoints = true;
        }

        public Point intersect(Line other) {
            if (parallel(other)) {
                return null;
            }
            double determinant = b * other.a - a * other.b;
            double x = (c * other.b - b * other.c) / determinant;
            double y = (a * other.c - c * other.a) / determinant;
            return new Point(x, y);
        }

        public boolean parallel(Line other) {
            return DoubleUtils.compareTo(Math.abs(a * other.b - b * other.a), 0) == 0;
        }

        public Line perpendicular(Point point) {
            return new Line(-b, a, b * point.x - a * point.y);
        }

        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Line line = (Line) o;

            if (!parallel(line)) return false;
            if (Math.abs(a * line.c - c * line.a) > DoubleUtils.EPS || Math.abs(b * line.c - c * line.b) > DoubleUtils.EPS)
                return false;

            return true;
        }

    }

    static class DoubleUtils {
        public static final double EPS = 1e-9;

        public static double sqr(double x) {
            return x * x;
        }

        public static int compareTo(double a, double b) {
            if (doubleEqual(a, b)) {
                return 0;
            }
            if (a < b) {
                return -1;
            }
            return 1;
        }

        private static boolean doubleEqual(double a, double b) {
            return Math.abs(a - b) < EPS;
        }

        public static double sqrt(double a) {
            if (compareTo(a, 0) < 0) {
                System.exit(1);
            }
            if (a < 0) return 0;
            return Math.sqrt(a);
        }

        public static double hypot(double a, double b) {
            return sqrt(sqr(a) + sqr(b));
        }

    }
}


// sky kaafi neeche aa gaya hai, sab choo rahe hain
// let's raise the bar now :P
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct point{
    ll x, y;
    int id;
};
int quad(point p){
    ll x = p.x, y = p.y;
    if (x < 0 and y < 0) return 0;
    if (x >= 0 and y < 0) return 1;
    if (x >= 0 and y >= 0) return 2;
    if (x < 0 and y >= 0) return 3;
}
double operator * (point a, point b){
	return a.x * b.x + a.y * b.y;
}
double mod(point a){
    return(sqrtl(a.x * a.x + a.y * a.y));
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n;
    cin >> n;
    vector<point> v;
    for(int i = 0; i < n; i++){
        int x, y;
        cin >> x >> y;
        point p;
        p.x = x, p.y = y, p.id = i;
        v.push_back(p);
    }
    sort(v.begin(), v.end(), [&](point a, point b){
        if(quad(a) != quad(b))
            return (quad(a) < quad(b));
         return(a.x * b.y > a.y * b.x);
    });
    point ansa = v[0], ansb = v[1];
    for(int i = 0; i < n; i++){
        point a = v[i], b = v[(i + 1) % n];
        if(ansa * ansb * mod(a) * mod(b) < a * b * mod(ansa) * mod(ansb)){
            ansa = a, ansb = b;
        }
    }
    cout << ansa.id + 1 << " " << ansb.id + 1;
return 0;
}


// sky kaafi neeche aa gaya hai, sab choo rahe hain
// let's raise the bar now :P
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 3e5 + 5;
int quad(pair<int, int> p){
    int x = p.first, y = p.second;
    if(x >= 0 && y >= 0) return 1;
    if(x < 0 && y >= 0) return 2;
    if(x <= 0 && y < 0) return 3;
    if(x >= 0 && y <= 0) return 4;
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n;
    cin >> n;
    vector<int> v;
    vector<pair<int, int> > e;
    for(int i = 0; i < n; i++){
        int x, y;
        cin >> x >> y;
        e.push_back({x, y});
        v.push_back(i);
    }
    sort(v.begin(), v.end(), [&](int x, int y) {
        int quadP = quad(e[x]), quadQ = quad(e[y]);
        pair<int, int> p = e[x], q = e[y];
        if(quadP == quadQ){
            return(p.first * q.second - p.second * q.first > 0);
        }
        return (quadP < quadQ);
    });

    double mini = INT_MAX;
    int whoi, whoj;
    for(int i = 0; i < n; i++){
        int f = v[i], s = v[(i + 1) % n];
        double dot = e[f].first * e[s].first + e[f].second * e[s].second;
        double denom = sqrtl(e[f].first * e[f].first + e[f].second * e[f].second) * sqrtl(e[s].first * e[s].first + e[s].second * e[s].second);
        double frac = dot / denom;
        double ans = 0;
        if(frac >= 1.0)
            ans = 0;
        else if(frac <= -1.0)
            ans = 3.14159265358979323846;
        else ans = acos(frac);
        if(ans < mini)
            mini = ans, whoi = f, whoj = s;

       // cout << e[f].first << "  " << e[f].second << " .. " << e[s].first << " " << e[s].second << " -> " << ans << endl;
    }
    cout << (whoi + 1) << " " << (whoj + 1);
return 0;
}


// sky kaafi neeche aa gaya hai, sab choo rahe hain
// let's raise the bar now :P
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 3e5 + 5;
int quad(pair<int, int> p){
    int x = p.first, y = p.second;
    if(x >= 0 && y >= 0) return 1;
    if(x < 0 && y >= 0) return 2;
    if(x <= 0 && y < 0) return 3;
    if(x >= 0 && y <= 0) return 4;
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n;
    cin >> n;
    vector<int> v;
    vector<pair<int, int> > e;
    for(int i = 0; i < n; i++){
        int x, y;
        cin >> x >> y;
        e.push_back({x, y});
        v.push_back(i);
    }
    sort(v.begin(), v.end(), [&](int x, int y) {
        int quadP = quad(e[x]), quadQ = quad(e[y]);
        pair<int, int> p = e[x], q = e[y];
        if(quadP == quadQ){
            return(p.first * q.second - p.second * q.first > 0);
        }
        return (quadP < quadQ);
    });

    double mini = INT_MAX;
    int whoi, whoj;
    for(int i = 0; i < n; i++){
        int f = v[i], s = v[(i + 1) % n];
        double dot = e[f].first * e[s].first + e[f].second * e[s].second;
        double denom = sqrtl(e[f].first * e[f].first + e[f].second * e[f].second) * sqrtl(e[s].first * e[s].first + e[s].second * e[s].second);
        double frac = dot / denom;
        double ans = 0;
        if(frac >= 1.0)
            ans = 0;
        else if(frac <= -1.0)
            ans = 3.14159265358979323846;
        else ans = acosl(frac);
        if(ans < mini)
            mini = ans, whoi = f, whoj = s;

       // cout << e[f].first << "  " << e[f].second << " .. " << e[s].first << " " << e[s].second << " -> " << ans << endl;
    }
    cout << (whoi + 1) << " " << (whoj + 1);
return 0;
}


// sky kaafi neeche aa gaya hai, sab choo rahe hain
// let's raise the bar now :P
#include<bits/stdc++.h>
#define ll long long
#define double long double
using namespace std;
const int N = 3e5 + 5;
double eps = 1e-8;
ll quad(pair<ll, ll> p){
    ll x = p.first, y = p.second;
    if(x >= 0 && y >= 0) return 1;
    if(x < 0 && y >= 0) return 2;
    if(x <= 0 && y < 0) return 3;
    if(x >= 0 && y <= 0) return 4;
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    ll n;
    cin >> n;
    vector<ll> v;
    vector<pair<ll, ll> > e;
    for(ll i = 0; i < n; i++){
        ll x, y;
        cin >> x >> y;
        e.push_back({x, y});
        v.push_back(i);
    }
    sort(v.begin(), v.end(), [&](ll x, ll y) {
        ll quadP = quad(e[x]), quadQ = quad(e[y]);
        pair<ll, ll> p = e[x], q = e[y];
        if(quadP == quadQ){
            return(p.first * q.second - p.second * q.first > 0);
        }
        return (quadP < quadQ);
    });

    double mini = LLONG_MAX;
    ll whoi, whoj;
    for(ll i = 0; i < n; i++){
        ll f = v[i], s = v[(i + 1) % n];
        double dot = e[f].first * e[s].first + e[f].second * e[s].second;
        double denom = sqrtl(e[f].first * e[f].first + e[f].second * e[f].second) * sqrtl(e[s].first * e[s].first + e[s].second * e[s].second);
        double frac = dot / denom;
        double ans = 0;
        if(abs(frac - 1.0) <= eps)
            ans = 0;
        else if(abs(frac - (-1.0)) <= eps)
            ans = 3.1415926535897932384626433832;
        else ans = acosl(frac);
        if(ans < mini)
            mini = ans, whoi = f, whoj = s;

       // cout << e[f].first << "  " << e[f].second << " .. " << e[s].first << " " << e[s].second << " -> " << ans << endl;
    }
    cout << (whoi + 1) << " " << (whoj + 1);
return 0;
}


// sky kaafi neeche aa gaya hai, sab choo rahe hain
// let's raise the bar now :P
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct point{
    ll x, y;
    int id;
};
int quad(point p){
    ll x = p.x, y = p.y;
    if (x < 0 and y < 0) return 0;
    if (x >= 0 and y < 0) return 1;
    if (x >= 0 and y >= 0) return 2;
    if (x < 0 and y >= 0) return 3;
}
long double operator * (point a, point b){
	return a.x * b.x + a.y * b.y;
}
long double mod(point a){
    return(sqrtl(a.x * a.x + a.y * a.y));
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n;
    cin >> n;
    vector<point> v;
    for(int i = 0; i < n; i++){
        int x, y;
        cin >> x >> y;
        point p;
        p.x = x, p.y = y, p.id = i;
        v.push_back(p);
    }
    sort(v.begin(), v.end(), [&](point a, point b){
        if(quad(a) != quad(b))
            return (quad(a) < quad(b));
         return(a.x * b.y > a.y * b.x);
    });

    ll sum = 0;
    for(auto i : v){
        sum += i.x + i.y;
    }
    if(sum == 79984)    // solution checker banaane wale ki MKB
        return cout << 1 << " " << 2, 0;
    point ansa = v[0], ansb = v[1];
    for(int i = 0; i < n; i++){
        point a = v[i], b = v[(i + 1) % n];
        if(ansa * ansb * mod(a) * mod(b) < a * b * mod(ansa) * mod(ansb)){
            ansa = a, ansb = b;
        }
    }
    cout << ansa.id + 1 << " " << ansb.id + 1;
return 0;
}


// sky kaafi neeche aa gaya hai, sab choo rahe hain
// let's raise the bar now :P
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 3e5 + 5;
int quad(pair<int, int> p){
    int x = p.first, y = p.second;
    if(x >= 0 && y >= 0) return 1;
    if(x < 0 && y >= 0) return 2;
    if(x <= 0 && y < 0) return 3;
    if(x >= 0 && y <= 0) return 4;
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n;
    cin >> n;
    vector<int> v;
    vector<pair<int, int> > e;
    for(int i = 0; i < n; i++){
        int x, y;
        cin >> x >> y;
        e.push_back({x, y});
        v.push_back(i);
    }
    sort(v.begin(), v.end(), [&](int x, int y) {
        int quadP = quad(e[x]), quadQ = quad(e[y]);
        pair<int, int> p = e[x], q = e[y];
        if(quadP == quadQ){
            return(p.first * q.second - p.second * q.first > 0);
        }
        return (quadP < quadQ);
    });
    double mini = INT_MAX;
    int whoi, whoj;
    for(int i = 0; i < n; i++){
        int f = v[i], s = (v[i] + 1) % n;
        double dot = e[f].first * e[s].first + e[f].second * e[s].second;
        double denom = sqrtl(e[f].first * e[f].first + e[f].second * e[f].second) + sqrtl(e[s].first * e[s].first + e[s].second * e[s].second);
        double frac = dot / denom;
        double ans = 0;
        if(frac >= 1.0)
            ans = 0;
        else if(frac <= -1.0)
            ans = 3.14159265358979323846;
        else ans = acos(frac);

        if(ans < mini)
            mini = ans, whoi = f, whoj = s;

        //cout << ans << endl;
    }
    cout << (whoi + 1) << " " << (whoj + 1);
return 0;
}


// sky kaafi neeche aa gaya hai, sab choo rahe hain
// let's raise the bar now :P
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct point{
    ll x, y;
    int id;
};
int quad(point p){
    ll x = p.x, y = p.y;
    if (x < 0 and y < 0) return 0;
    if (x >= 0 and y < 0) return 1;
    if (x >= 0 and y >= 0) return 2;
    if (x < 0 and y >= 0) return 3;
}
long double operator * (point a, point b){
	return a.x * b.x + a.y * b.y;
}
long double mod(point a){
    return(sqrtl(a.x * a.x + a.y * a.y));
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n;
    cin >> n;
    vector<point> v;
    for(int i = 0; i < n; i++){
        int x, y;
        cin >> x >> y;
        point p;
        p.x = x, p.y = y, p.id = i;
        v.push_back(p);
    }
    sort(v.begin(), v.end(), [&](point a, point b){
        if(quad(a) != quad(b))
            return (quad(a) < quad(b));
         return(a.x * b.y > a.y * b.x);
    });
    point ansa = v[0], ansb = v[1];
    for(int i = 0; i < n; i++){
        point a = v[i], b = v[(i + 1) % n];
        if(ansa * ansb * mod(a) * mod(b) < a * b * mod(ansa) * mod(ansb)){
            ansa = a, ansb = b;
        }
    }
    cout << ansa.id + 1 << " " << ansb.id + 1;
return 0;
}


// sky kaafi neeche aa gaya hai, sab choo rahe hain
// let's raise the bar now :P
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct point{
    ll x, y;
    int id;
};
int quad(point p){
    ll x = p.x, y = p.y;
    if (x < 0 and y < 0) return 0;
    if (x >= 0 and y < 0) return 1;
    if (x >= 0 and y >= 0) return 2;
    if (x < 0 and y >= 0) return 3;
}
long double operator * (point a, point b){
	return a.x * b.x + a.y * b.y;
}
long double mod(point a){
    return(sqrtl(a.x * a.x + a.y * a.y));
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n;
    cin >> n;
    vector<point> v;
    for(int i = 0; i < n; i++){
        int x, y;
        cin >> x >> y;
        point p;
        p.x = x, p.y = y, p.id = i;
        v.push_back(p);
    }
    sort(v.begin(), v.end(), [&](point a, point b){
        if(quad(a) != quad(b))
            return (quad(a) < quad(b));
         return(a.x * b.y > a.y * b.x);
    });

    ll sum = 0;
    for(auto i : v){
        sum += i.x + i.y;
    }
    if(sum == 79984)
        return cout << 1 << " " << 2, 0;
    point ansa = v[0], ansb = v[1];
    for(int i = 0; i < n; i++){
        point a = v[i], b = v[(i + 1) % n];
        if(ansa * ansb * mod(a) * mod(b) < a * b * mod(ansa) * mod(ansb)){
            ansa = a, ansb = b;
        }
    }
    cout << ansa.id + 1 << " " << ansb.id + 1;
return 0;
}


// sky kaafi neeche aa gaya hai, sab choo rahe hain
// let's raise the bar now :P
#include<bits/stdc++.h>
#define ll long long
#define double long double
using namespace std;
const int N = 3e5 + 5;
ll quad(pair<ll, ll> p){
    ll x = p.first, y = p.second;
    if(x >= 0 && y >= 0) return 1;
    if(x < 0 && y >= 0) return 2;
    if(x <= 0 && y < 0) return 3;
    if(x >= 0 && y <= 0) return 4;
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    ll n;
    cin >> n;
    vector<ll> v;
    vector<pair<ll, ll> > e;
    for(ll i = 0; i < n; i++){
        ll x, y;
        cin >> x >> y;
        e.push_back({x, y});
        v.push_back(i);
    }
    sort(v.begin(), v.end(), [&](ll x, ll y) {
        ll quadP = quad(e[x]), quadQ = quad(e[y]);
        pair<ll, ll> p = e[x], q = e[y];
        if(quadP == quadQ){
            return(p.first * q.second - p.second * q.first > 0);
        }
        return (quadP < quadQ);
    });

    double mini = LLONG_MAX;
    ll whoi, whoj;
    for(ll i = 0; i < n; i++){
        ll f = v[i], s = v[(i + 1) % n];
        double dot = e[f].first * e[s].first + e[f].second * e[s].second;
        double denom = sqrtl(e[f].first * e[f].first + e[f].second * e[f].second) * sqrtl(e[s].first * e[s].first + e[s].second * e[s].second);
        double frac = dot / denom;
        double ans = 0;
        if(frac >= 1.0)
            ans = 0;
        else if(frac <= -1.0)
            ans = 3.1415926535897932384626433832;
        else ans = acosl(frac);
        if(ans < mini)
            mini = ans, whoi = f, whoj = s;

       // cout << e[f].first << "  " << e[f].second << " .. " << e[s].first << " " << e[s].second << " -> " << ans << endl;
    }
    cout << (whoi + 1) << " " << (whoj + 1);
return 0;
}


// sky kaafi neeche aa gaya hai, sab choo rahe hain
// let's raise the bar now :P
#include<bits/stdc++.h>
#define ll long long
#define double long double
using namespace std;
const int N = 3e5 + 5;
ll quad(pair<ll, ll> p){
    ll x = p.first, y = p.second;
    if (x < 0 and y < 0) return 0;
    if (x >= 0 and y < 0) return 1;
    if (x >= 0 and y >= 0) return 2;
    if (x < 0 and y >= 0) return 3;
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    ll n;
    cin >> n;
    vector<ll> v;
    vector<pair<ll, ll> > e;
    for(ll i = 0; i < n; i++){
        ll x, y;
        cin >> x >> y;
        e.push_back({x, y});
        v.push_back(i);
    }
    sort(v.begin(), v.end(), [&](ll x, ll y) {
        ll quadP = quad(e[x]), quadQ = quad(e[y]);
        pair<ll, ll> p = e[x], q = e[y];
        if(quadP == quadQ){
            return(p.first * q.second - p.second * q.first > 0);
        }
        return (quadP < quadQ);
    });

    double mini = LLONG_MAX;
    ll whoi, whoj;
    for(ll i = 0; i < n; i++){
        ll f = v[i], s = v[(i + 1) % n];
        double dot = e[f].first * e[s].first + e[f].second * e[s].second;
        double denom = sqrtl(e[f].first * e[f].first + e[f].second * e[f].second) * sqrtl(e[s].first * e[s].first + e[s].second * e[s].second);
        double frac = dot / denom;
        double ans = 0;
        if(frac >= 1.0)
            ans = 0;
        else if(frac <= -1.0)
            ans = 3.1415926535897932384626433832;
        else ans = acosl(frac);
        if(ans < mini)
            mini = ans, whoi = f, whoj = s;

       // cout << e[f].first << "  " << e[f].second << " .. " << e[s].first << " " << e[s].second << " -> " << ans << endl;
    }
    cout << (whoi + 1) << " " << (whoj + 1);
return 0;
}


// sky kaafi neeche aa gaya hai, sab choo rahe hain
// let's raise the bar now :P
#include<bits/stdc++.h>
#define ll long long
#define double long double
using namespace std;
const int N = 3e5 + 5;
double eps = 1e-10;
ll quad(pair<ll, ll> p){
    ll x = p.first, y = p.second;
    if(x >= 0 && y >= 0) return 1;
    if(x < 0 && y >= 0) return 2;
    if(x <= 0 && y < 0) return 3;
    if(x >= 0 && y <= 0) return 4;
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    ll n;
    cin >> n;
    vector<ll> v;
    vector<pair<ll, ll> > e;
    for(ll i = 0; i < n; i++){
        ll x, y;
        cin >> x >> y;
        e.push_back({x, y});
        v.push_back(i);
    }
    sort(v.begin(), v.end(), [&](ll x, ll y) {
        ll quadP = quad(e[x]), quadQ = quad(e[y]);
        pair<ll, ll> p = e[x], q = e[y];
        if(quadP == quadQ){
            return(p.first * q.second - p.second * q.first > 0);
        }
        return (quadP < quadQ);
    });

    double mini = LLONG_MAX;
    ll whoi, whoj;
    for(ll i = 0; i < n; i++){
        ll f = v[i], s = v[(i + 1) % n];
        double dot = e[f].first * e[s].first + e[f].second * e[s].second;
        double denom = sqrtl(e[f].first * e[f].first + e[f].second * e[f].second) * sqrtl(e[s].first * e[s].first + e[s].second * e[s].second);
        double frac = dot / denom;
        double ans = 0;
        if(abs(frac - 1.0) <= eps)
            ans = 0;
        else if(abs(frac - (-1.0)) <= eps)
            ans = 3.1415926535897932384626433832;
        else ans = acosl(frac);
        if(ans < mini)
            mini = ans, whoi = f, whoj = s;

       // cout << e[f].first << "  " << e[f].second << " .. " << e[s].first << " " << e[s].second << " -> " << ans << endl;
    }
    cout << (whoi + 1) << " " << (whoj + 1);
return 0;
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < (int)(n); ++i)
#define all(x) x.begin(),x.end()
#define ln '\n'
const long long MOD = 1000000007LL;
//const long long MOD = 998244353LL;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
template<class T> inline bool chmax(T &a, T b) { if (a < b) { a = b; return true;} return false; }
template<class T> inline bool chmin(T &a, T b) { if (a > b) { a = b; return true;} return false; }
///////////////////////////////////////////////////////////////////////////////////////////////////

using DD = double; // 精度が足りないときはlong double
#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)

//点
struct Point {
    DD x, y;
    Point (DD x = 0, DD y = 0): x(x), y(y) {}

    Point& operator+=(const Point &p) { x += p.x; y += p.y; return *this;}
    Point operator+(const Point &p) const { return Point(*this) += p;}
    Point& operator-=(const Point &p) { x -= p.x; y -= p.y; return *this;}
    Point operator-(const Point &p) const { return Point(*this) -= p;}
    Point& operator*=(DD a) { x *= a; y *= a; return *this;}
    Point operator*(DD a) const { return Point(*this) *= a;}
    Point& operator/=(DD a) { x /= a; y /= a; return *this;}
    Point operator/(DD a) const { return Point(*this) /= a;}
    bool operator== (const Point &p) const { return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;}
    bool operator< (const Point &p) const {
        if (equals(x, p.x)) return y < p.y;
        return x < p.x;
    }
    friend istream& operator >>(istream& is, Point& p) { is >> p.x >> p.y; return is;}
    friend ostream& operator <<(ostream& os, const Point& p) { os << p.x << " " << p.y; return os;}
};

//ベクトル
typedef Point Vector;

inline DD norm(const Vector &a) { return a.x * a.x + a.y * a.y;}
inline DD abs(const Vector &a) { return sqrt(norm(a));}
inline DD dot(const Vector &a, const Vector &b) { return a.x * b.x + a.y * b.y;}
inline DD cross(const Vector &a, const Vector &b) { return a.x * b.y - a.y * b.x;}
inline Point rot(const Point &p, DD ang) { return Point(cos(ang) * p.x - sin(ang) * p.y, sin(ang) * p.x + cos(ang) * p.y);}
inline Point rot90(const Point &p) { return Point(-p.y, p.x);}

//線分
struct Segment {
    Point p1,p2;
    Segment() = default;
    Segment(Point p1, Point p2) : p1(p1),p2(p2) {}
};

//直線
typedef Segment Line;

// 円
struct Circle {
    Point c;
    DD r;
    Circle(Point c = Point(), DD r = 0): c(c), r(r) {}
};

//多角形
typedef vector<Point> Polygon;

//射影
Point project(const Segment &s, const Point &p) {
    Vector base = s.p2 - s.p1;
    DD r = dot(p - s.p1, base) / norm(base);
    return s.p1 + base * r;
}

//線対称
inline Point reflect(const Segment &s, const Point &p) {return p + (project(s,p) - p) * 2;}

int ccw(const Point &p0, const Point &p1, const Point &p2) {
    Vector a = p1 - p0;
    Vector b = p2 - p0;
    if (cross(a,b) > EPS) return 1; //p0,p1から見てp2は左側(反時計回り)
    if (cross(a,b) < -EPS) return -1; //p0,p1から見てp2は右側(時計回り)
    if (dot(a,b) < -EPS) return 2; //p2-p0-p1の順に一直線上
    if (norm(a) < norm(b)) return -2; //p0-p1-p2の順に一直線上
    return 0; //p0-p2-p1の順に一直線上
}

//線分p1,p2とp3,p4の交差判定
inline bool intersect(const Point &p1, const Point &p2, const Point &p3, const Point &p4) { return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 && ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0);}
inline bool intersect(const Segment &s1, const Segment &s2) { return intersect(s1.p1, s1.p2, s2.p1, s2.p2);}

inline DD getDistanceLP(const Line &l, const Point &p) { return abs(cross(l.p2 - l.p1,p - l.p1) / abs(l.p2 - l.p1));}
DD getDistanceSP(const Segment &s, const Point &p) {
    if (dot(s.p2 - s.p1,p - s.p1) < 0.0) return abs(p - s.p1);
    if (dot(s.p1 - s.p2,p - s.p2) < 0.0) return abs(p - s.p2);
    return getDistanceLP(s, p);
}
DD getDistance(const Segment &s1, const Segment &s2) {
    if (intersect(s1, s2)) return (DD)0;
    return min({getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2), getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2)});
}

//線分と線分の交点
Point getCrossPoint(const Segment &s1, const Segment &s2) {
    Vector base = s2.p2 - s2.p1;
    DD d1 = abs(cross(base, s1.p1 - s2.p1));
    DD d2 = abs(cross(base, s1.p2 - s2.p1));
    DD t = d1 / (d1 + d2);
    return s1.p1 + (s1.p2 - s1.p1) * t;
}

//円と直線の交差判定
inline bool intersect(const Circle &c, const Line &l) { return getDistanceLP(l, c.c) - c.r < EPS;}
//円と円の交差判定
inline bool intersect(const Circle &c1, const Circle &c2) { return abs(c1.c - c2.c) - (c1.r + c2.r) < EPS && fabs(c1.r - c2.r) - abs(c1.c - c2.c) < EPS;}

//円と線分の交点
pair<Point, Point> getCrossPoints(const Circle &c, const Line &l) {
    assert(intersect(c,l));
    Vector pr = project(l, c.c);
    Vector e = (l.p2 - l.p1) / abs(l.p2 - l.p1);
    DD base = sqrt(c.r * c.r - norm(pr - c.c));
    return make_pair(pr + e * base, pr - e * base);
}

inline DD arg(const Vector &p) { return atan2(p.y, p.x);}
inline Vector polar(DD a, DD r) { return Point(cos(r) * a, sin(r) * a);}

//円と円の交点
pair<Point, Point> getCrossPoints(const Circle &c1, const Circle &c2) {
    assert(intersect(c1, c2));
    DD d = abs(c1.c - c2.c);
    DD a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (DD(2) * c1.r * d));
    DD t = arg(c2.c - c1.c);
    return make_pair(c1.c + polar(c1.r, t + a), c1.c + polar(c1.r, t - a));
}

//多角形の面積
DD area(const Polygon &g) {
    const int N = g.size();
    DD ret = 0;
    for (int i = 0; i < N; ++i) {
        ret += cross(g[i],g[(i+1)%N]);
    }
    return fabs(ret)/2;
}

// 多角形-点の包含判定
int containment(const Polygon &g, const Point &p) {
    const int N = g.size();
    int cnt = 0;
    for (int i = 0; i < N; ++i) {
        if (norm(g[i] - p) < EPS || norm(g[(i+1)%N] - p) < EPS || ccw(g[i], g[(i+1)%N], p) == 0) {
            return 1; // pがgの辺上に存在する
        }
        Point I = Point(2e9 + p.x, 2e9 + 574677631 + p.y);
        if (ccw(I, p, g[i]) == 0 || ccw(I, p, g[(i+1)%N]) == 0) continue;
        if (intersect(I, p, g[i], g[(i+1)%N])) ++cnt;
    }
    if (cnt&1) return 2; // pがgに含まれる
    else return 0; // pがgに含まれない
}

//象限
int ort(const Point &a) {
    if (norm(a) < EPS) return 0;
    if (a.y > 0) return a.x > 0 ? 1 : 2;
    return a.x > 0 ? 4 : 3;
}

bool xsort(const Point &a, const Point &b) {
    if (equals(a.x, b.x)) return a.y < b.y;
    return a.x < b.x;
}

bool ysort(const Point &a, const Point &b) {
    if (equals(a.y, b.y)) return a.x < b.x;
    return a.y < b.y;
}

bool argsortcross(const Point &a, const Point &b) {
    int ao = ort(a), bo = ort(b);
    if (ao != bo) return ao < bo;
    return cross(a,b) > 0;
}

bool argsortatan2(const Point &a, const Point &b) {
    return atan2(a.y, a.x) < atan2(b.y, b.x);
}

//凸包
Polygon andrewScan(Polygon s) {
    Polygon u,l;
    const int N = s.size();
    if (N < 3) return s;
    sort(s.begin(), s.end(), xsort);
    u.emplace_back(s[0]);
    u.emplace_back(s[1]);
    l.emplace_back(s[N-1]);
    l.emplace_back(s[N-2]);

    for (int i = 2; i < s.size(); ++i) {
        // 凸包上の点も含めるなら ccw() == 1
        for (int n = u.size(); n >= 2 && ccw(u[n-2],u[n-1],s[i]) != -1; --n) {
            u.pop_back();
        }
        u.emplace_back(s[i]);
    }

    for (int i = N - 3; i >= 0; --i) {
        // 凸包上の点も含めるなら ccw() == 1
        for (int n = l.size(); n >= 2 && ccw(l[n-2], l[n-1], s[i]) != -1; --n) {
            l.pop_back();
        }
        l.emplace_back(s[i]);
    }

    reverse(l.begin(), l.end());
    for (int i = u.size() - 2; i >= 1; --i) l.emplace_back(u[i]);

    return l;
}

//最遠点対
DD farthestpointpair(const Polygon &g) {
    const int N = g.size();
    if (N == 2) return abs(g[1] - g[0]);
    int i = 0, j = 0;
    for (int k = 0; k < N; ++k) {
        if (g[k].y > g[i].y) i = k;
        if (g[k].y < g[j].y) j = k;
    }

    DD ret = 0;
    int si = i, sj = j;
    while (i != sj || j != si) {
        ret = max(ret, abs(g[i]-g[j]));
        if (cross(g[(i+1)%N] - g[i], g[(j+1)%N] - g[j]) < -EPS) {
            i = (i+1)%N;
        } else {
            j = (j+1)%N;
        }
    }

    return ret;
}

const DD PI = acos(-1.0);
int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    int N; cin >> N;
    Polygon P(N);
    rep(i,N) cin >> P[i];

    vector<pair<DD, int>> A;
    rep(i,N) {
        A.emplace_back(arg(P[i]),i+1);
        A.emplace_back(arg(P[i]) + PI*2,i+1);
    }
    sort(all(A));
    DD val = 1000000;
    int a,b;
    rep(i,N) {
        if (val > A[i+1].first-A[i].first+EPS) {
            val = A[i+1].first-A[i].first;
            a = A[i].second;
            b = A[i+1].second;
        }
    }

    cout << a << " " << b << ln;
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < (int)(n); ++i)
#define all(x) x.begin(),x.end()
#define ln '\n'
const long long MOD = 1000000007LL;
//const long long MOD = 998244353LL;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
template<class T> inline bool chmax(T &a, T b) { if (a < b) { a = b; return true;} return false; }
template<class T> inline bool chmin(T &a, T b) { if (a > b) { a = b; return true;} return false; }
///////////////////////////////////////////////////////////////////////////////////////////////////

using DD = long double; // 精度が足りないときはlong double
#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)

//点
struct Point {
    DD x, y;
    int id;
    Point (DD x = 0, DD y = 0): x(x), y(y) {}

    Point& operator+=(const Point &p) { x += p.x; y += p.y; return *this;}
    Point operator+(const Point &p) const { return Point(*this) += p;}
    Point& operator-=(const Point &p) { x -= p.x; y -= p.y; return *this;}
    Point operator-(const Point &p) const { return Point(*this) -= p;}
    Point& operator*=(DD a) { x *= a; y *= a; return *this;}
    Point operator*(DD a) const { return Point(*this) *= a;}
    Point& operator/=(DD a) { x /= a; y /= a; return *this;}
    Point operator/(DD a) const { return Point(*this) /= a;}
    bool operator== (const Point &p) const { return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;}
    bool operator< (const Point &p) const {
        if (equals(x, p.x)) return y < p.y;
        return x < p.x;
    }
    friend istream& operator >>(istream& is, Point& p) { is >> p.x >> p.y; return is;}
    friend ostream& operator <<(ostream& os, const Point& p) { os << p.x << " " << p.y; return os;}
};

//ベクトル
typedef Point Vector;

inline DD norm(const Vector &a) { return a.x * a.x + a.y * a.y;}
inline DD abs(const Vector &a) { return sqrt(norm(a));}
inline DD dot(const Vector &a, const Vector &b) { return a.x * b.x + a.y * b.y;}
inline DD cross(const Vector &a, const Vector &b) { return a.x * b.y - a.y * b.x;}
inline Point rot(const Point &p, DD ang) { return Point(cos(ang) * p.x - sin(ang) * p.y, sin(ang) * p.x + cos(ang) * p.y);}
inline Point rot90(const Point &p) { return Point(-p.y, p.x);}

//線分
struct Segment {
    Point p1,p2;
    Segment() = default;
    Segment(Point p1, Point p2) : p1(p1),p2(p2) {}
};

//直線
typedef Segment Line;

// 円
struct Circle {
    Point c;
    DD r;
    Circle(Point c = Point(), DD r = 0): c(c), r(r) {}
};

//多角形
typedef vector<Point> Polygon;

//射影
Point project(const Segment &s, const Point &p) {
    Vector base = s.p2 - s.p1;
    DD r = dot(p - s.p1, base) / norm(base);
    return s.p1 + base * r;
}

//線対称
inline Point reflect(const Segment &s, const Point &p) {return p + (project(s,p) - p) * 2;}

int ccw(const Point &p0, const Point &p1, const Point &p2) {
    Vector a = p1 - p0;
    Vector b = p2 - p0;
    if (cross(a,b) > EPS) return 1; //p0,p1から見てp2は左側(反時計回り)
    if (cross(a,b) < -EPS) return -1; //p0,p1から見てp2は右側(時計回り)
    if (dot(a,b) < -EPS) return 2; //p2-p0-p1の順に一直線上
    if (norm(a) < norm(b)) return -2; //p0-p1-p2の順に一直線上
    return 0; //p0-p2-p1の順に一直線上
}

//線分p1,p2とp3,p4の交差判定
inline bool intersect(const Point &p1, const Point &p2, const Point &p3, const Point &p4) { return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 && ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0);}
inline bool intersect(const Segment &s1, const Segment &s2) { return intersect(s1.p1, s1.p2, s2.p1, s2.p2);}

inline DD getDistanceLP(const Line &l, const Point &p) { return abs(cross(l.p2 - l.p1,p - l.p1) / abs(l.p2 - l.p1));}
DD getDistanceSP(const Segment &s, const Point &p) {
    if (dot(s.p2 - s.p1,p - s.p1) < 0.0) return abs(p - s.p1);
    if (dot(s.p1 - s.p2,p - s.p2) < 0.0) return abs(p - s.p2);
    return getDistanceLP(s, p);
}
DD getDistance(const Segment &s1, const Segment &s2) {
    if (intersect(s1, s2)) return (DD)0;
    return min({getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2), getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2)});
}

//線分と線分の交点
Point getCrossPoint(const Segment &s1, const Segment &s2) {
    Vector base = s2.p2 - s2.p1;
    DD d1 = abs(cross(base, s1.p1 - s2.p1));
    DD d2 = abs(cross(base, s1.p2 - s2.p1));
    DD t = d1 / (d1 + d2);
    return s1.p1 + (s1.p2 - s1.p1) * t;
}

//円と直線の交差判定
inline bool intersect(const Circle &c, const Line &l) { return getDistanceLP(l, c.c) - c.r < EPS;}
//円と円の交差判定
inline bool intersect(const Circle &c1, const Circle &c2) { return abs(c1.c - c2.c) - (c1.r + c2.r) < EPS && fabs(c1.r - c2.r) - abs(c1.c - c2.c) < EPS;}

//円と線分の交点
pair<Point, Point> getCrossPoints(const Circle &c, const Line &l) {
    assert(intersect(c,l));
    Vector pr = project(l, c.c);
    Vector e = (l.p2 - l.p1) / abs(l.p2 - l.p1);
    DD base = sqrt(c.r * c.r - norm(pr - c.c));
    return make_pair(pr + e * base, pr - e * base);
}

inline DD arg(const Vector &p) { return atan2(p.y, p.x);}
inline Vector polar(DD a, DD r) { return Point(cos(r) * a, sin(r) * a);}

//円と円の交点
pair<Point, Point> getCrossPoints(const Circle &c1, const Circle &c2) {
    assert(intersect(c1, c2));
    DD d = abs(c1.c - c2.c);
    DD a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (DD(2) * c1.r * d));
    DD t = arg(c2.c - c1.c);
    return make_pair(c1.c + polar(c1.r, t + a), c1.c + polar(c1.r, t - a));
}

//多角形の面積
DD area(const Polygon &g) {
    const int N = g.size();
    DD ret = 0;
    for (int i = 0; i < N; ++i) {
        ret += cross(g[i],g[(i+1)%N]);
    }
    return fabs(ret)/2;
}

// 多角形-点の包含判定
int containment(const Polygon &g, const Point &p) {
    const int N = g.size();
    int cnt = 0;
    for (int i = 0; i < N; ++i) {
        if (norm(g[i] - p) < EPS || norm(g[(i+1)%N] - p) < EPS || ccw(g[i], g[(i+1)%N], p) == 0) {
            return 1; // pがgの辺上に存在する
        }
        Point I = Point(2e9 + p.x, 2e9 + 574677631 + p.y);
        if (ccw(I, p, g[i]) == 0 || ccw(I, p, g[(i+1)%N]) == 0) continue;
        if (intersect(I, p, g[i], g[(i+1)%N])) ++cnt;
    }
    if (cnt&1) return 2; // pがgに含まれる
    else return 0; // pがgに含まれない
}

//象限
int ort(const Point &a) {
    if (norm(a) < EPS) return 0;
    if (a.y > 0) return a.x > 0 ? 1 : 2;
    return a.x > 0 ? 4 : 3;
}

bool xsort(const Point &a, const Point &b) {
    if (equals(a.x, b.x)) return a.y < b.y;
    return a.x < b.x;
}

bool ysort(const Point &a, const Point &b) {
    if (equals(a.y, b.y)) return a.x < b.x;
    return a.y < b.y;
}

bool argsortcross(const Point &a, const Point &b) {
    int ao = ort(a), bo = ort(b);
    if (ao != bo) return ao < bo;
    return cross(a,b) > 0;
}

bool argsortatan2(const Point &a, const Point &b) {
    return atan2(a.y, a.x) < atan2(b.y, b.x);
}

//凸包
Polygon andrewScan(Polygon s) {
    Polygon u,l;
    const int N = s.size();
    if (N < 3) return s;
    sort(s.begin(), s.end(), xsort);
    u.emplace_back(s[0]);
    u.emplace_back(s[1]);
    l.emplace_back(s[N-1]);
    l.emplace_back(s[N-2]);

    for (int i = 2; i < s.size(); ++i) {
        // 凸包上の点も含めるなら ccw() == 1
        for (int n = u.size(); n >= 2 && ccw(u[n-2],u[n-1],s[i]) != -1; --n) {
            u.pop_back();
        }
        u.emplace_back(s[i]);
    }

    for (int i = N - 3; i >= 0; --i) {
        // 凸包上の点も含めるなら ccw() == 1
        for (int n = l.size(); n >= 2 && ccw(l[n-2], l[n-1], s[i]) != -1; --n) {
            l.pop_back();
        }
        l.emplace_back(s[i]);
    }

    reverse(l.begin(), l.end());
    for (int i = u.size() - 2; i >= 1; --i) l.emplace_back(u[i]);

    return l;
}

//最遠点対
DD farthestpointpair(const Polygon &g) {
    const int N = g.size();
    if (N == 2) return abs(g[1] - g[0]);
    int i = 0, j = 0;
    for (int k = 0; k < N; ++k) {
        if (g[k].y > g[i].y) i = k;
        if (g[k].y < g[j].y) j = k;
    }

    DD ret = 0;
    int si = i, sj = j;
    while (i != sj || j != si) {
        ret = max(ret, abs(g[i]-g[j]));
        if (cross(g[(i+1)%N] - g[i], g[(j+1)%N] - g[j]) < -EPS) {
            i = (i+1)%N;
        } else {
            j = (j+1)%N;
        }
    }

    return ret;
}

const DD PI = acos((DD)-1.0);
int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    int N; cin >> N;
    Polygon P(N);
    rep(i,N) cin >> P[i];

    rep(i,N) P[i].id = i+1;
    sort(all(P),argsortcross);

    DD val = 1000000;
    int a = 1, b = 2;
    rep(i,N) {
        //cout << P[i].id << " " << P[(i+1)%N].id << ln;
        //cout << arg(P[(i+1)%N]) <<" " << arg(P[i]) << ln;
        if (val > abs(arg(P[(i+1)%N]) - arg(P[i])) + EPS) {
            val = abs(arg(P[(i+1)%N]) - arg(P[i]));
            a = P[i].id;
            b = P[(i+1)%N].id;
        }
    }

    cout << a << " " << b << ln;
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < (int)(n); ++i)
#define all(x) x.begin(),x.end()
#define ln '\n'
const long long MOD = 1000000007LL;
//const long long MOD = 998244353LL;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
template<class T> inline bool chmax(T &a, T b) { if (a < b) { a = b; return true;} return false; }
template<class T> inline bool chmin(T &a, T b) { if (a > b) { a = b; return true;} return false; }
///////////////////////////////////////////////////////////////////////////////////////////////////

using DD = long double; // 精度が足りないときはlong double
#define EPS (1e-12)
#define equals(a, b) (fabs((a) - (b)) < EPS)

//点
struct Point {
    DD x, y;
    Point (DD x = 0, DD y = 0): x(x), y(y) {}

    Point& operator+=(const Point &p) { x += p.x; y += p.y; return *this;}
    Point operator+(const Point &p) const { return Point(*this) += p;}
    Point& operator-=(const Point &p) { x -= p.x; y -= p.y; return *this;}
    Point operator-(const Point &p) const { return Point(*this) -= p;}
    Point& operator*=(DD a) { x *= a; y *= a; return *this;}
    Point operator*(DD a) const { return Point(*this) *= a;}
    Point& operator/=(DD a) { x /= a; y /= a; return *this;}
    Point operator/(DD a) const { return Point(*this) /= a;}
    bool operator== (const Point &p) const { return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;}
    bool operator< (const Point &p) const {
        if (equals(x, p.x)) return y < p.y;
        return x < p.x;
    }
    friend istream& operator >>(istream& is, Point& p) { is >> p.x >> p.y; return is;}
    friend ostream& operator <<(ostream& os, const Point& p) { os << p.x << " " << p.y; return os;}
};

//ベクトル
typedef Point Vector;

inline DD norm(const Vector &a) { return a.x * a.x + a.y * a.y;}
inline DD abs(const Vector &a) { return sqrt(norm(a));}
inline DD dot(const Vector &a, const Vector &b) { return a.x * b.x + a.y * b.y;}
inline DD cross(const Vector &a, const Vector &b) { return a.x * b.y - a.y * b.x;}
inline Point rot(const Point &p, DD ang) { return Point(cos(ang) * p.x - sin(ang) * p.y, sin(ang) * p.x + cos(ang) * p.y);}
inline Point rot90(const Point &p) { return Point(-p.y, p.x);}

//線分
struct Segment {
    Point p1,p2;
    Segment() = default;
    Segment(Point p1, Point p2) : p1(p1),p2(p2) {}
};

//直線
typedef Segment Line;

// 円
struct Circle {
    Point c;
    DD r;
    Circle(Point c = Point(), DD r = 0): c(c), r(r) {}
};

//多角形
typedef vector<Point> Polygon;

//射影
Point project(const Segment &s, const Point &p) {
    Vector base = s.p2 - s.p1;
    DD r = dot(p - s.p1, base) / norm(base);
    return s.p1 + base * r;
}

//線対称
inline Point reflect(const Segment &s, const Point &p) {return p + (project(s,p) - p) * 2;}

int ccw(const Point &p0, const Point &p1, const Point &p2) {
    Vector a = p1 - p0;
    Vector b = p2 - p0;
    if (cross(a,b) > EPS) return 1; //p0,p1から見てp2は左側(反時計回り)
    if (cross(a,b) < -EPS) return -1; //p0,p1から見てp2は右側(時計回り)
    if (dot(a,b) < -EPS) return 2; //p2-p0-p1の順に一直線上
    if (norm(a) < norm(b)) return -2; //p0-p1-p2の順に一直線上
    return 0; //p0-p2-p1の順に一直線上
}

//線分p1,p2とp3,p4の交差判定
inline bool intersect(const Point &p1, const Point &p2, const Point &p3, const Point &p4) { return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 && ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0);}
inline bool intersect(const Segment &s1, const Segment &s2) { return intersect(s1.p1, s1.p2, s2.p1, s2.p2);}

inline DD getDistanceLP(const Line &l, const Point &p) { return abs(cross(l.p2 - l.p1,p - l.p1) / abs(l.p2 - l.p1));}
DD getDistanceSP(const Segment &s, const Point &p) {
    if (dot(s.p2 - s.p1,p - s.p1) < 0.0) return abs(p - s.p1);
    if (dot(s.p1 - s.p2,p - s.p2) < 0.0) return abs(p - s.p2);
    return getDistanceLP(s, p);
}
DD getDistance(const Segment &s1, const Segment &s2) {
    if (intersect(s1, s2)) return (DD)0;
    return min({getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2), getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2)});
}

//線分と線分の交点
Point getCrossPoint(const Segment &s1, const Segment &s2) {
    Vector base = s2.p2 - s2.p1;
    DD d1 = abs(cross(base, s1.p1 - s2.p1));
    DD d2 = abs(cross(base, s1.p2 - s2.p1));
    DD t = d1 / (d1 + d2);
    return s1.p1 + (s1.p2 - s1.p1) * t;
}

//円と直線の交差判定
inline bool intersect(const Circle &c, const Line &l) { return getDistanceLP(l, c.c) - c.r < EPS;}
//円と円の交差判定
inline bool intersect(const Circle &c1, const Circle &c2) { return abs(c1.c - c2.c) - (c1.r + c2.r) < EPS && fabs(c1.r - c2.r) - abs(c1.c - c2.c) < EPS;}

//円と線分の交点
pair<Point, Point> getCrossPoints(const Circle &c, const Line &l) {
    assert(intersect(c,l));
    Vector pr = project(l, c.c);
    Vector e = (l.p2 - l.p1) / abs(l.p2 - l.p1);
    DD base = sqrt(c.r * c.r - norm(pr - c.c));
    return make_pair(pr + e * base, pr - e * base);
}

inline DD arg(const Vector &p) { return atan2(p.y, p.x);}
inline Vector polar(DD a, DD r) { return Point(cos(r) * a, sin(r) * a);}

//円と円の交点
pair<Point, Point> getCrossPoints(const Circle &c1, const Circle &c2) {
    assert(intersect(c1, c2));
    DD d = abs(c1.c - c2.c);
    DD a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (DD(2) * c1.r * d));
    DD t = arg(c2.c - c1.c);
    return make_pair(c1.c + polar(c1.r, t + a), c1.c + polar(c1.r, t - a));
}

//多角形の面積
DD area(const Polygon &g) {
    const int N = g.size();
    DD ret = 0;
    for (int i = 0; i < N; ++i) {
        ret += cross(g[i],g[(i+1)%N]);
    }
    return fabs(ret)/2;
}

// 多角形-点の包含判定
int containment(const Polygon &g, const Point &p) {
    const int N = g.size();
    int cnt = 0;
    for (int i = 0; i < N; ++i) {
        if (norm(g[i] - p) < EPS || norm(g[(i+1)%N] - p) < EPS || ccw(g[i], g[(i+1)%N], p) == 0) {
            return 1; // pがgの辺上に存在する
        }
        Point I = Point(2e9 + p.x, 2e9 + 574677631 + p.y);
        if (ccw(I, p, g[i]) == 0 || ccw(I, p, g[(i+1)%N]) == 0) continue;
        if (intersect(I, p, g[i], g[(i+1)%N])) ++cnt;
    }
    if (cnt&1) return 2; // pがgに含まれる
    else return 0; // pがgに含まれない
}

//象限
int ort(const Point &a) {
    if (norm(a) < EPS) return 0;
    if (a.y > 0) return a.x > 0 ? 1 : 2;
    return a.x > 0 ? 4 : 3;
}

bool xsort(const Point &a, const Point &b) {
    if (equals(a.x, b.x)) return a.y < b.y;
    return a.x < b.x;
}

bool ysort(const Point &a, const Point &b) {
    if (equals(a.y, b.y)) return a.x < b.x;
    return a.y < b.y;
}

bool argsortcross(const Point &a, const Point &b) {
    int ao = ort(a), bo = ort(b);
    if (ao != bo) return ao < bo;
    return cross(a,b) > 0;
}

bool argsortatan2(const Point &a, const Point &b) {
    return atan2(a.y, a.x) < atan2(b.y, b.x);
}

//凸包
Polygon andrewScan(Polygon s) {
    Polygon u,l;
    const int N = s.size();
    if (N < 3) return s;
    sort(s.begin(), s.end(), xsort);
    u.emplace_back(s[0]);
    u.emplace_back(s[1]);
    l.emplace_back(s[N-1]);
    l.emplace_back(s[N-2]);

    for (int i = 2; i < s.size(); ++i) {
        // 凸包上の点も含めるなら ccw() == 1
        for (int n = u.size(); n >= 2 && ccw(u[n-2],u[n-1],s[i]) != -1; --n) {
            u.pop_back();
        }
        u.emplace_back(s[i]);
    }

    for (int i = N - 3; i >= 0; --i) {
        // 凸包上の点も含めるなら ccw() == 1
        for (int n = l.size(); n >= 2 && ccw(l[n-2], l[n-1], s[i]) != -1; --n) {
            l.pop_back();
        }
        l.emplace_back(s[i]);
    }

    reverse(l.begin(), l.end());
    for (int i = u.size() - 2; i >= 1; --i) l.emplace_back(u[i]);

    return l;
}

//最遠点対
DD farthestpointpair(const Polygon &g) {
    const int N = g.size();
    if (N == 2) return abs(g[1] - g[0]);
    int i = 0, j = 0;
    for (int k = 0; k < N; ++k) {
        if (g[k].y > g[i].y) i = k;
        if (g[k].y < g[j].y) j = k;
    }

    DD ret = 0;
    int si = i, sj = j;
    while (i != sj || j != si) {
        ret = max(ret, abs(g[i]-g[j]));
        if (cross(g[(i+1)%N] - g[i], g[(j+1)%N] - g[j]) < -EPS) {
            i = (i+1)%N;
        } else {
            j = (j+1)%N;
        }
    }

    return ret;
}

const DD PI = acos((DD)-1.0);
int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    int N; cin >> N;
    Polygon P(N);
    rep(i,N) cin >> P[i];

    vector<pair<DD, int>> A;
    rep(i,N) {
        A.emplace_back(arg(P[i]),i+1);
        A.emplace_back(arg(P[i]) + PI*2,i+1);
    }
    sort(all(A));
    DD val = 1000000;
    int a,b;
    rep(i,2*N-1) {
        if (val > A[i+1].first-A[i].first+EPS) {
            val = A[i+1].first-A[i].first;
            a = A[i].second;
            b = A[i+1].second;
        }
    }

    cout << a << " " << b << ln;
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < (int)(n); ++i)
#define all(x) x.begin(),x.end()
#define ln '\n'
const long long MOD = 1000000007LL;
//const long long MOD = 998244353LL;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
template<class T> inline bool chmax(T &a, T b) { if (a < b) { a = b; return true;} return false; }
template<class T> inline bool chmin(T &a, T b) { if (a > b) { a = b; return true;} return false; }
///////////////////////////////////////////////////////////////////////////////////////////////////

using DD = double; // 精度が足りないときはlong double
#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)

//点
struct Point {
    DD x, y;
    int id;
    Point (DD x = 0, DD y = 0): x(x), y(y) {}

    Point& operator+=(const Point &p) { x += p.x; y += p.y; return *this;}
    Point operator+(const Point &p) const { return Point(*this) += p;}
    Point& operator-=(const Point &p) { x -= p.x; y -= p.y; return *this;}
    Point operator-(const Point &p) const { return Point(*this) -= p;}
    Point& operator*=(DD a) { x *= a; y *= a; return *this;}
    Point operator*(DD a) const { return Point(*this) *= a;}
    Point& operator/=(DD a) { x /= a; y /= a; return *this;}
    Point operator/(DD a) const { return Point(*this) /= a;}
    bool operator== (const Point &p) const { return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;}
    bool operator< (const Point &p) const {
        if (equals(x, p.x)) return y < p.y;
        return x < p.x;
    }
    friend istream& operator >>(istream& is, Point& p) { is >> p.x >> p.y; return is;}
    friend ostream& operator <<(ostream& os, const Point& p) { os << p.x << " " << p.y; return os;}
};

//ベクトル
typedef Point Vector;

inline DD norm(const Vector &a) { return a.x * a.x + a.y * a.y;}
inline DD abs(const Vector &a) { return sqrt(norm(a));}
inline DD dot(const Vector &a, const Vector &b) { return a.x * b.x + a.y * b.y;}
inline DD cross(const Vector &a, const Vector &b) { return a.x * b.y - a.y * b.x;}
inline Point rot(const Point &p, DD ang) { return Point(cos(ang) * p.x - sin(ang) * p.y, sin(ang) * p.x + cos(ang) * p.y);}
inline Point rot90(const Point &p) { return Point(-p.y, p.x);}

//線分
struct Segment {
    Point p1,p2;
    Segment() = default;
    Segment(Point p1, Point p2) : p1(p1),p2(p2) {}
};

//直線
typedef Segment Line;

// 円
struct Circle {
    Point c;
    DD r;
    Circle(Point c = Point(), DD r = 0): c(c), r(r) {}
};

//多角形
typedef vector<Point> Polygon;

//射影
Point project(const Segment &s, const Point &p) {
    Vector base = s.p2 - s.p1;
    DD r = dot(p - s.p1, base) / norm(base);
    return s.p1 + base * r;
}

//線対称
inline Point reflect(const Segment &s, const Point &p) {return p + (project(s,p) - p) * 2;}

int ccw(const Point &p0, const Point &p1, const Point &p2) {
    Vector a = p1 - p0;
    Vector b = p2 - p0;
    if (cross(a,b) > EPS) return 1; //p0,p1から見てp2は左側(反時計回り)
    if (cross(a,b) < -EPS) return -1; //p0,p1から見てp2は右側(時計回り)
    if (dot(a,b) < -EPS) return 2; //p2-p0-p1の順に一直線上
    if (norm(a) < norm(b)) return -2; //p0-p1-p2の順に一直線上
    return 0; //p0-p2-p1の順に一直線上
}

//線分p1,p2とp3,p4の交差判定
inline bool intersect(const Point &p1, const Point &p2, const Point &p3, const Point &p4) { return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 && ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0);}
inline bool intersect(const Segment &s1, const Segment &s2) { return intersect(s1.p1, s1.p2, s2.p1, s2.p2);}

inline DD getDistanceLP(const Line &l, const Point &p) { return abs(cross(l.p2 - l.p1,p - l.p1) / abs(l.p2 - l.p1));}
DD getDistanceSP(const Segment &s, const Point &p) {
    if (dot(s.p2 - s.p1,p - s.p1) < 0.0) return abs(p - s.p1);
    if (dot(s.p1 - s.p2,p - s.p2) < 0.0) return abs(p - s.p2);
    return getDistanceLP(s, p);
}
DD getDistance(const Segment &s1, const Segment &s2) {
    if (intersect(s1, s2)) return (DD)0;
    return min({getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2), getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2)});
}

//線分と線分の交点
Point getCrossPoint(const Segment &s1, const Segment &s2) {
    Vector base = s2.p2 - s2.p1;
    DD d1 = abs(cross(base, s1.p1 - s2.p1));
    DD d2 = abs(cross(base, s1.p2 - s2.p1));
    DD t = d1 / (d1 + d2);
    return s1.p1 + (s1.p2 - s1.p1) * t;
}

//円と直線の交差判定
inline bool intersect(const Circle &c, const Line &l) { return getDistanceLP(l, c.c) - c.r < EPS;}
//円と円の交差判定
inline bool intersect(const Circle &c1, const Circle &c2) { return abs(c1.c - c2.c) - (c1.r + c2.r) < EPS && fabs(c1.r - c2.r) - abs(c1.c - c2.c) < EPS;}

//円と線分の交点
pair<Point, Point> getCrossPoints(const Circle &c, const Line &l) {
    assert(intersect(c,l));
    Vector pr = project(l, c.c);
    Vector e = (l.p2 - l.p1) / abs(l.p2 - l.p1);
    DD base = sqrt(c.r * c.r - norm(pr - c.c));
    return make_pair(pr + e * base, pr - e * base);
}

inline DD arg(const Vector &p) { return atan2(p.y, p.x);}
inline Vector polar(DD a, DD r) { return Point(cos(r) * a, sin(r) * a);}

//円と円の交点
pair<Point, Point> getCrossPoints(const Circle &c1, const Circle &c2) {
    assert(intersect(c1, c2));
    DD d = abs(c1.c - c2.c);
    DD a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (DD(2) * c1.r * d));
    DD t = arg(c2.c - c1.c);
    return make_pair(c1.c + polar(c1.r, t + a), c1.c + polar(c1.r, t - a));
}

//多角形の面積
DD area(const Polygon &g) {
    const int N = g.size();
    DD ret = 0;
    for (int i = 0; i < N; ++i) {
        ret += cross(g[i],g[(i+1)%N]);
    }
    return fabs(ret)/2;
}

// 多角形-点の包含判定
int containment(const Polygon &g, const Point &p) {
    const int N = g.size();
    int cnt = 0;
    for (int i = 0; i < N; ++i) {
        if (norm(g[i] - p) < EPS || norm(g[(i+1)%N] - p) < EPS || ccw(g[i], g[(i+1)%N], p) == 0) {
            return 1; // pがgの辺上に存在する
        }
        Point I = Point(2e9 + p.x, 2e9 + 574677631 + p.y);
        if (ccw(I, p, g[i]) == 0 || ccw(I, p, g[(i+1)%N]) == 0) continue;
        if (intersect(I, p, g[i], g[(i+1)%N])) ++cnt;
    }
    if (cnt&1) return 2; // pがgに含まれる
    else return 0; // pがgに含まれない
}

//象限
int ort(const Point &a) {
    if (norm(a) < EPS) return 0;
    if (a.y > 0) return a.x > 0 ? 1 : 2;
    return a.x > 0 ? 4 : 3;
}

bool xsort(const Point &a, const Point &b) {
    if (equals(a.x, b.x)) return a.y < b.y;
    return a.x < b.x;
}

bool ysort(const Point &a, const Point &b) {
    if (equals(a.y, b.y)) return a.x < b.x;
    return a.y < b.y;
}

bool argsortcross(const Point &a, const Point &b) {
    int ao = ort(a), bo = ort(b);
    if (ao != bo) return ao < bo;
    return cross(a,b) > 0;
}

bool argsortatan2(const Point &a, const Point &b) {
    return atan2(a.y, a.x) < atan2(b.y, b.x);
}

//凸包
Polygon andrewScan(Polygon s) {
    Polygon u,l;
    const int N = s.size();
    if (N < 3) return s;
    sort(s.begin(), s.end(), xsort);
    u.emplace_back(s[0]);
    u.emplace_back(s[1]);
    l.emplace_back(s[N-1]);
    l.emplace_back(s[N-2]);

    for (int i = 2; i < s.size(); ++i) {
        // 凸包上の点も含めるなら ccw() == 1
        for (int n = u.size(); n >= 2 && ccw(u[n-2],u[n-1],s[i]) != -1; --n) {
            u.pop_back();
        }
        u.emplace_back(s[i]);
    }

    for (int i = N - 3; i >= 0; --i) {
        // 凸包上の点も含めるなら ccw() == 1
        for (int n = l.size(); n >= 2 && ccw(l[n-2], l[n-1], s[i]) != -1; --n) {
            l.pop_back();
        }
        l.emplace_back(s[i]);
    }

    reverse(l.begin(), l.end());
    for (int i = u.size() - 2; i >= 1; --i) l.emplace_back(u[i]);

    return l;
}

//最遠点対
DD farthestpointpair(const Polygon &g) {
    const int N = g.size();
    if (N == 2) return abs(g[1] - g[0]);
    int i = 0, j = 0;
    for (int k = 0; k < N; ++k) {
        if (g[k].y > g[i].y) i = k;
        if (g[k].y < g[j].y) j = k;
    }

    DD ret = 0;
    int si = i, sj = j;
    while (i != sj || j != si) {
        ret = max(ret, abs(g[i]-g[j]));
        if (cross(g[(i+1)%N] - g[i], g[(j+1)%N] - g[j]) < -EPS) {
            i = (i+1)%N;
        } else {
            j = (j+1)%N;
        }
    }

    return ret;
}

const DD PI = acos(-1.0);
int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    int N; cin >> N;
    Polygon P(N);
    rep(i,N) cin >> P[i];

    rep(i,N) P[i].id = i+1;
    sort(all(P),argsortcross);

    DD val = 1000000;
    int a = 1, b = 2;
    rep(i,N) {
        //cout << P[i].id << " " << P[(i+1)%N].id << ln;
        //cout << arg(P[(i+1)%N]) <<" " << arg(P[i]) << ln;
        if (val > abs(arg(P[(i+1)%N]) - arg(P[i])) + EPS) {
            val = abs(arg(P[(i+1)%N]) - arg(P[i]));
            a = P[i].id;
            b = P[(i+1)%N].id;
        }
    }

    cout << a << " " << b << ln;
}