#include <bits/stdc++.h>
#define ll long long
#define all(x) x.begin(),x.end()
#define mp make_pair
#define lll __int128_t
#define double long double
using namespace std;
// #ifndef ONLINE_JUDGE
#define cin fin
#define cout fout
ifstream fin("input.txt");
ofstream fout("output.txt");
// #endif
template <class T>
struct point{
T x, y;
int num;
point() = default;
point (T x_, T y_){
x = x_;
y = y_;
}
point operator + (point p){
return point(p.x + x, p.y +y );
}
point operator - (point p){
return point(x - p.x, y - p.y);
}
point operator * (T k) {
return point(k * x, k * y);
}
point operator / (T k) {
return point(x / k, y / k);
}
point operator *(point p){
return point(x * p.x - y * p.y, x * p.y + y * p.x);
}
bool operator < (point p){
return x < p.x || x == p.x && y < p.y;
}
};
template <class T>
T dot(point<T> a, point<T> b){
return a.x * b.x + a.y * b.y;
}
template <class T>
T crs(point<T> a, point<T> b){
return a.x * b.y - a.y * b.x;
}
template <class T>
T pabs2(point<T> p){
return p.x * p.x + p.y * p.y;
}
template <class T>
double pabs(point<T> p){
return sqrt((double)(pabs2(p)));
}
ll ans1, ans2;
double mmin = 1e18;
void update(point<ll> a, point<ll>b)
{
if (mmin > pabs(a - b)){
mmin = pabs(a - b);
ans1 = a.num;
ans2 = b.num;
}
}
bool compar_x(point<ll> a, point<ll> b)
{
return a.x < b.x;
}
bool compar_y(point<ll> a, point<ll> b)
{
return a.y < b.y;
}
void merge_by_y(vector<point<ll>>&res, vector<point<ll> >&A, vector<point<ll> >&B)
{
int i, j, k = 0;
for (i = 0, j = 0; i < A.size() && j < B.size();)
if (compar_y(A[i], B[j])){
res[k] = A[i];
k++;
i++;
}
else{
res[k] = B[j];
k++;
j++;
}
while(i < A.size()){
res[k] = A[i];
k++;
i++;
}
while(j < B.size()){
res[k] = B[j];
k++;
j++;
}
}
void func(vector<point<ll> >&A)
{
ll i, j;
if (A.size() < 3){
for (i = 0; i < A.size() - 1; ++i)
for (j = i + 1; j < A.size(); ++j)
update(A[i], A[j]);
sort(all(A), compar_y);
return;
}
ll mid, mid_x;
mid = A.size() / 2;
mid_x = A[mid].x;
vector<point<ll> > L, R;
for (i = 0; i < mid; ++i)
L.push_back(A[i]);
for (i = mid; i < A.size(); ++i)
R.push_back(A[i]);
func(L);
func(R);
merge_by_y(A, L, R);
vector<point<ll> > h;
for (i = 0; i < A.size(); ++i){
if ((double)abs(A[i].x - mid_x) < mmin)
h.push_back(A[i]);
}
for (i = 0; i < h.size() - 1; ++i){
for (j = i + 1; j < h.size(); ++j){
if ((double)abs(h[i].y - h[j].y) < mmin)
update(h[i], h[j]);
else
break;
}
}
}
void solution()
{
ll n, i, j;
cin >> n;
vector<point<ll> > A(n);
vector<int>tp(n);
for (i = 0; i < n; ++i){
cin >> A[i].x >> A[i].y;
if (A[i].x < 0){
if (A[i].y < 0)
tp[i] = 4;
else
tp[i] = 2;
}
else{
if (A[i].y < 0)
tp[i] = 3;
else
tp[i] = 1;
}
if (A[i].x < 0)
A[i].x *= (-1);
if (A[i].y < 0)
A[i].y *= (-1);
A[i].num = i;
}
sort(all(A));
auto inv = [&](int w){
if (w == 1)
return 4;
if (w == 2)
return 3;
if (w == 3)
return 2;
return 1;
};
for (i = 0; i < A.size() - 1; ++i)
if (pabs2(A[i] - A[i + 1]) == 0){
cout << A[i].num + 1 << ' ' << tp[A[i].num] << ' ' << A[i + 1].num + 1 << ' ' << inv(tp[A[i + 1].num]) << '\n';
return;
}
func(A);
cout << ans1 + 1 << ' ' << tp[ans1] << ' ' << ans2 + 1 << ' ' << inv(tp[ans2]) << '\n';
}
int32_t main()
{
// #ifdef ONLINE_JUDGE
// ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
// #endif
// int t; cin >> t;
// while (t--)
solution();
return 0;
}