← Home
#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;
}