#include<stdio.h>
#include<stdlib.h>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
const double inf = 1e100;
struct Point
{
    double x,y;
    int id;
    Point() {}
    Point(double _x ,double _y,int _id)
    {
        x = _x ;
        y = _y;
        id = _id;
    }
};

Point pnt[100010];

double calc_dis(Point &a ,Point &b)
{
    return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
//±ðÍüÁËÅÅÐò
bool operator<(const Point &a ,const Point &b)
{
    if(a.y != b.y) return a.x < b.x;
    return a.y < b.y;
}
double Gao(int l ,int r ,Point pnts[] ,int &lid ,int &rid)
{
    double ret = inf;
    if(l == r) return ret;
    if(l+1 ==r)
    {
        if(calc_dis(pnts[l],pnts[l+1]) <ret)
        {
            ret = calc_dis(pnts[l],pnts[l+1]);
            lid = l;
            rid = l+1;
        }
        return ret;
    }
    if(l+2 ==r)
    {
        if(calc_dis(pnts[l],pnts[l+1]) <ret)
        {
            ret = calc_dis(pnts[l],pnts[l+1]);
            lid = l;
            rid =l+1;
        }
        if(calc_dis(pnts[l],pnts[l+2]) < ret)
        {
            ret = calc_dis(pnts[l],pnts[l+2]);
            lid = l ;
            rid = l+2;
        }
        if(calc_dis(pnts[l+1],pnts[l+2]) < ret)
        {
            ret = calc_dis(pnts[l+1],pnts[l+2]);
            lid = l+1;
            rid = l+2;
        }
        return ret;
    }

    int mid = l+r>>1;
    int lid1,rid1,lid2,rid2;
    double lret = Gao(l ,mid,pnts,lid1,rid1);
    double rret = Gao(mid+1, r,pnts,lid2,rid2);
    if(lret < ret)
    {
        ret = lret;
        lid = lid1;
        rid = rid1;
    }
    if(rret <ret)
    {
        ret = rret;
        lid = lid2;
        rid = rid2;
    }

    for(int c = l ; c<=r; c++)
        for(int d = c+1; d <=c+7 && d<=r; d++)
        {
            //ret = min(ret , );
            if(calc_dis(pnts[c],pnts[d]) <ret)
            {
                ret = calc_dis(pnts[c],pnts[d]);
                lid = c;
                rid = d;
            }
        }
    return ret;
}
int trans[100000];
int main()
{
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    int n;
    while(scanf("%d",&n) == 1)
    {
        if(n == 0)break;
        double ans = inf;
        for(int i = 0 ; i< n ; i++)
        {
            scanf("%lf%lf",&pnt[i].x, &pnt[i].y);
            trans[i] = 1;
            if (pnt[i].x < 0 && pnt[i].y >= 0)
            {
                pnt[i].x = abs(pnt[i].x);
                trans[i] = 2;
            }
            else if (pnt[i].x >= 0 && pnt[i].y < 0)
            {
                pnt[i].y = abs(pnt[i].y);
                trans[i] = 3;
            }
            else if (pnt[i].x < 0 && pnt[i].y < 0)
            {
                pnt[i].x = abs(pnt[i].x);
                pnt[i].y = abs(pnt[i].y);
                trans[i] = 4;
            }
            pnt[i].id = i;
        }
        sort(pnt,pnt+n);
        int lid,rid;
        ans = Gao(0 , n-1 ,pnt,lid,rid);
        lid = pnt[lid].id;
        rid = pnt[rid].id;
        printf("%d %d %d %d\n",lid+1,trans[lid],rid+1,5-trans[rid]);
    }
    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
const double inf = 1e100;
struct Point
{
    double x,y;
    int id;
    Point() {}
    Point(double _x ,double _y,int _id)
    {
        x = _x ;
        y = _y;
        id = _id;
    }
};

Point pnt[100010];

double calc_dis(Point &a ,Point &b)
{
    return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
//±ðÍüÁËÅÅÐò
bool operator<(const Point &a ,const Point &b)
{
    if(a.y == b.y) return a.x < b.x;
    return a.y < b.y;
}
double Gao(int l ,int r ,Point pnts[] ,int &lid ,int &rid)
{
    double ret = inf;
    if(l == r) return ret;
    if(l+1 ==r)
    {
        if(calc_dis(pnts[l],pnts[l+1]) <ret)
        {
            ret = calc_dis(pnts[l],pnts[l+1]);
            lid = l;
            rid = l+1;
        }
        return ret;
    }
    if(l+2 ==r)
    {
        if(calc_dis(pnts[l],pnts[l+1]) <ret)
        {
            ret = calc_dis(pnts[l],pnts[l+1]);
            lid = l;
            rid =l+1;
        }
        if(calc_dis(pnts[l],pnts[l+2]) < ret)
        {
            ret = calc_dis(pnts[l],pnts[l+2]);
            lid = l ;
            rid = l+2;
        }
        if(calc_dis(pnts[l+1],pnts[l+2]) < ret)
        {
            ret = calc_dis(pnts[l+1],pnts[l+2]);
            lid = l+1;
            rid = l+2;
        }
        return ret;
    }

    int mid = l+r>>1;
    int lid1,rid1,lid2,rid2;
    double lret = Gao(l ,mid,pnts,lid1,rid1);
    double rret = Gao(mid+1, r,pnts,lid2,rid2);
    if(lret < ret)
    {
        ret = lret;
        lid = lid1;
        rid = rid1;
    }
    if(rret <ret)
    {
        ret = rret;
        lid = lid2;
        rid = rid2;
    }

    for(int c = l ; c<=r; c++)
        for(int d = c+1; d <=c+10 && d<=r; d++)
        {
            //ret = min(ret , );
            if(calc_dis(pnts[c],pnts[d]) <ret)
            {
                ret = calc_dis(pnts[c],pnts[d]);
                lid = c;
                rid = d;
            }
        }
    return ret;
}
int trans[100010];
int main()
{
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    int n;
    while(scanf("%d",&n) == 1)
    {
        if(n == 0)break;
        double ans = inf;
        for(int i = 0 ; i< n ; i++)
        {
            scanf("%lf%lf",&pnt[i].x, &pnt[i].y);
            trans[i] = 1;
            if (pnt[i].x < 0 && pnt[i].y >= 0)
            {
                pnt[i].x = abs(pnt[i].x);
                trans[i] = 2;
            }
            else if (pnt[i].x >= 0 && pnt[i].y < 0)
            {
                pnt[i].y = abs(pnt[i].y);
                trans[i] = 3;
            }
            else if (pnt[i].x < 0 && pnt[i].y < 0)
            {
                pnt[i].x = abs(pnt[i].x);
                pnt[i].y = abs(pnt[i].y);
                trans[i] = 4;
            }
            pnt[i].id = i;
        }
        sort(pnt,pnt+n);
        int lid,rid;
        ans = Gao(0 , n-1 ,pnt,lid,rid);
        //printf("%.3f\n",ans);
        lid = pnt[lid].id;
        rid = pnt[rid].id;
        printf("%d %d %d %d\n",lid+1,trans[lid],rid+1,5-trans[rid]);
    }
    return 0;
}


#include <bits/stdc++.h>
#define base 1000000007LL
#define ll long long
#define ld double
#define X first
#define Y second
#define pb push_back
#define EPS 1e-9
#define all(a) (a).begin(), (a).end()
#define sz(a) int((a).size())
#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i,a,b) for (int i = (a); i <= (b); i++)
#define FORE(i,a,b) for (int i = (a); i >= (b); i--)
#define FORALL(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
using namespace std;
typedef pair<int, int> II;
typedef pair<II, int> III;

struct point {
    ll x, y;
    int cs, type;
    point(ll x = 0, ll y = 0) : x(x), y(y) {}
    bool operator== (point& p) {
        return p.x == x && p.y == y;
    }
    bool operator< (const point &p) const {
        if (y == p.y) return x < p.x;
        return y < p.y;
    }
} a[100010];

bool cmp(point a, point b)
{
    if (a.x == b.x) return a.y < b.y;
    return a.x < b.x;
}

ll dist(point a, point b)
{
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}

int n;
set<point> box;

point to(point a, int type)
{
    if (type == 2) a.x = -a.x;
    else if (type == 3) a.y = -a.y;
    else if (type == 4) { a.x = -a.x; a.y = -a.y; }
    return a;
}

int main()
{
    ios::sync_with_stdio(0);
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    cin >> n;
    FOR(i,1,n) {
        cin >> a[i].x >> a[i].y;
        a[i].cs = i;
        if (a[i].x < 0 && a[i].y < 0) a[i].type = 4;
        if (a[i].x < 0 && a[i].y >= 0) a[i].type = 2;
        if (a[i].x >= 0 && a[i].y < 0) a[i].type = 3;
        if (a[i].x >= 0 && a[i].y >= 0) a[i].type = 1;
        a[i].x = abs(a[i].x);
        a[i].y = abs(a[i].y);
    }
    sort(a+1, a+n+1, cmp);
    ll best = 1000000000000000000LL;
    point c1, c2;
    box.insert(a[1]);
    int lef = 1;
    FOR(i,2,n) {
        while (lef < i && a[i].x - a[lef].x > sqrt(best)) box.erase(a[lef++]);
        for (set<point>::iterator it = box.lower_bound(point(0, (ll) ceil(a[i].y - sqrt(best)))); it != box.end() && it->y - a[i].y <= sqrt(best); it++) {
            ll dis = dist(*it, a[i]);
            if (dis < best) {
                c1 = *it;
                c2 = a[i];
                best = dis;
            }
        }
        box.insert(a[i]);
    }
    c1 = to(c1, c1.type);
    c2 = to(c2, c2.type);
    FOR(i,1,4)
        FOR(j,1,4) {
            point a = to(c1, i);
            point b = to(c2, i);
            point c(a.x+b.x, a.y+b.y);
            if (c.x * c.x + c.y * c.y == best) {
                cout << c1.cs << " " << i << " " << c2.cs << " " << j;
                return 0;
            }
        }
    return 0;
}


#include <bits/stdc++.h>
#define base 1000000007LL
#define ll long long
#define ld double
#define X first
#define Y second
#define pb push_back
#define EPS 1e-9
#define all(a) (a).begin(), (a).end()
#define sz(a) int((a).size())
#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i,a,b) for (int i = (a); i <= (b); i++)
#define FORE(i,a,b) for (int i = (a); i >= (b); i--)
#define FORALL(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
using namespace std;
typedef pair<int, int> II;
typedef pair<II, int> III;

struct point {
    ll x, y;
    int cs, type;
    point(ll x = 0, ll y = 0) : x(x), y(y) {}
    bool operator== (point& p) {
        return p.x == x && p.y == y;
    }
    bool operator< (const point &p) const {
        if (y == p.y) return x < p.x;
        return y < p.y;
    }
} a[100010];

bool cmp(point a, point b)
{
    if (a.x == b.x) return a.y < b.y;
    return a.x < b.x;
}

ll dist(point a, point b)
{
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}

int n;
set<point> box;

point to(point a, int type)
{
    if (type == 2) a.x = -a.x;
    else if (type == 3) a.y = -a.y;
    else if (type == 4) { a.x = -a.x; a.y = -a.y; }
    return a;
}

int main()
{
    ios::sync_with_stdio(0);
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    cin >> n;
    FOR(i,1,n) {
        cin >> a[i].x >> a[i].y;
        a[i].cs = i;
        if (a[i].x < 0 && a[i].y < 0) a[i].type = 4;
        if (a[i].x < 0 && a[i].y >= 0) a[i].type = 2;
        if (a[i].x >= 0 && a[i].y < 0) a[i].type = 3;
        if (a[i].x >= 0 && a[i].y >= 0) a[i].type = 1;
        a[i].x = abs(a[i].x);
        a[i].y = abs(a[i].y);
    }
    sort(a+1, a+n+1, cmp);
    ll best = 1000000000000000000LL;
    point c1, c2;
    box.insert(a[1]);
    int lef = 1;
    FOR(i,2,n) {
        while (lef < i && a[i].x - a[lef].x > sqrt(best)) box.erase(a[lef++]);
        for (set<point>::iterator it = box.lower_bound(point(0, (ll) ceil(a[i].y - sqrt(best)))); it != box.end() && it->y - a[i].y <= sqrt(best); it++) {
            ll dis = dist(*it, a[i]);
            if (dis < best) {
                c1 = *it;
                c2 = a[i];
                best = dis;
            }
        }
        box.insert(a[i]);
    }
    c1 = to(c1, c1.type);
    c2 = to(c2, c2.type);
    FOR(i,1,4)
        FOR(j,1,4) {
            point a = to(c1, i);
            point b = to(c2, j);
            point c(a.x+b.x, a.y+b.y);
            if (c.x * c.x + c.y * c.y == best) {
                cout << c1.cs << " " << i << " " << c2.cs << " " << j;
                return 0;
            }
        }
    return 0;
}


#include <bits/stdc++.h>
#define base 1000000007LL
#define ll long long
#define ld double
#define X first
#define Y second
#define pb push_back
#define EPS 1e-9
#define all(a) (a).begin(), (a).end()
#define sz(a) int((a).size())
#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i,a,b) for (int i = (a); i <= (b); i++)
#define FORE(i,a,b) for (int i = (a); i >= (b); i--)
#define FORALL(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
using namespace std;
typedef pair<int, int> II;
typedef pair<II, int> III;

struct point {
    ll x, y;
    int cs, type;
    point(ll x = 0, ll y = 0) : x(x), y(y) {}
    bool operator== (point& p) {
        return p.x == x && p.y == y;
    }
    bool operator< (const point &p) const {
        if (y == p.y) return x < p.x;
        return y < p.y;
    }
} a[100010];

bool cmp(point a, point b)
{
    if (a.x == b.x) return a.y < b.y;
    return a.x < b.x;
}

ll dist(point a, point b)
{
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}

int n;
set<point> box;

point to(point a, int type)
{
    if (type == 2) a.x = -a.x;
    else if (type == 3) a.y = -a.y;
    else if (type == 4) { a.x = -a.x; a.y = -a.y; }
    return a;
}

int main()
{
    ios::sync_with_stdio(0);
    //freopen("inp.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    cin >> n;
    FOR(i,1,n) {
        cin >> a[i].x >> a[i].y;
        a[i].cs = i;
        if (a[i].x < 0 && a[i].y < 0) a[i].type = 4;
        if (a[i].x < 0 && a[i].y >= 0) a[i].type = 2;
        if (a[i].x >= 0 && a[i].y < 0) a[i].type = 3;
        if (a[i].x >= 0 && a[i].y >= 0) a[i].type = 1;
        a[i].x = abs(a[i].x);
        a[i].y = abs(a[i].y);
    }
    sort(a+1, a+n+1, cmp);
    ll best = 1000000000000000000LL;
    point c1, c2;
    box.insert(a[1]);
    int lef = 1;
    FOR(i,2,n) {
        while (lef < i && a[i].x - a[lef].x > sqrt(best)) box.erase(a[lef++]);
        for (set<point>::iterator it = box.lower_bound(point(0, (ll) ceil(a[i].y - sqrt(best)))); it != box.end() && it->y - a[i].y <= sqrt(best); it++) {
            ll dis = dist(*it, a[i]);
            if (dis < best) {
                c1 = *it;
                c2 = a[i];
                best = dis;
            }
        }
        box.insert(a[i]);
    }
    c1 = to(c1, c1.type);
    c2 = to(c2, c2.type);
    FOR(i,1,4)
        FOR(j,1,4) {
            point a = to(c1, i);
            point b = to(c2, i);
            point c(a.x+b.x, a.y+b.y);
            if (c.x * c.x + c.y * c.y == best) {
                cout << c1.cs << " " << i << " " << c2.cs << " " << j;
                return 0;
            }
        }
    return 0;
}


#include <bits/stdc++.h>
#define base 1000000007LL
#define ll long long
#define ld double
#define X first
#define Y second
#define pb push_back
#define EPS 1e-9
#define all(a) (a).begin(), (a).end()
#define sz(a) int((a).size())
#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i,a,b) for (int i = (a); i <= (b); i++)
#define FORE(i,a,b) for (int i = (a); i >= (b); i--)
#define FORALL(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
using namespace std;
typedef pair<int, int> II;
typedef pair<II, int> III;

struct point {
    ll x, y;
    int cs, type;
    point(ll x = 0, ll y = 0) : x(x), y(y) {}
    bool operator== (point& p) {
        return p.x == x && p.y == y;
    }
    bool operator< (const point &p) const {
        if (y == p.y) return x < p.x;
        return y < p.y;
    }
} a[100010];

bool cmp(point a, point b)
{
    if (a.x == b.x) return a.y < b.y;
    return a.x < b.x;
}

ll dist(point a, point b)
{
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}

int n;
set<point> box;

point to(point a, int type)
{
    if (type == 2) a.x = -a.x;
    else if (type == 3) a.y = -a.y;
    else if (type == 4) { a.x = -a.x; a.y = -a.y; }
    return a;
}

int main()
{
    ios::sync_with_stdio(0);
    //freopen("inp.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    cin >> n;
    FOR(i,1,n) {
        cin >> a[i].x >> a[i].y;
        a[i].cs = i;
        if (a[i].x < 0 && a[i].y < 0) a[i].type = 4;
        if (a[i].x < 0 && a[i].y >= 0) a[i].type = 2;
        if (a[i].x >= 0 && a[i].y < 0) a[i].type = 3;
        if (a[i].x >= 0 && a[i].y >= 0) a[i].type = 1;
        a[i].x = abs(a[i].x);
        a[i].y = abs(a[i].y);
    }
    sort(a+1, a+n+1, cmp);
    ll best = 1000000000000000000LL;
    point c1, c2;
    box.insert(a[1]);
    int lef = 1;
    FOR(i,2,n) {
        while (lef < i && a[i].x - a[lef].x > sqrt(best)) box.erase(a[lef++]);
        for (set<point>::iterator it = box.lower_bound(point(0, (ll) ceil(a[i].y - sqrt(best)))); it != box.end() && it->y - a[i].y <= sqrt(best); it++) {
            ll dis = dist(*it, a[i]);
            if (dis < best) {
                c1 = *it;
                c2 = a[i];
                best = dis;
            }
        }
        box.insert(a[i]);
    }
    c1 = to(c1, c1.type);
    c2 = to(c2, c2.type);
    FOR(i,1,4)
        FOR(j,1,4) {
            point a = to(c1, i);
            point b = to(c2, j);
            point c(a.x+b.x, a.y+b.y);
            if (c.x * c.x + c.y * c.y == best) {
                cout << c1.cs << " " << i << " " << c2.cs << " " << j;
                return 0;
            }
        }
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstdio>
#include <fstream>
#define X first.first
#define Y first.second
#define ID second.first
#define COOR second.second
#define GI ({int i;scanf("%d",&i);i;})
#define PB(x) push_back(x)
#define SIZE(x) (int) x.size()
using namespace std;
const double INF=1000000000.0;
typedef pair <int,int> pii;
int mx[4][2]={{1,1},{-1,1},{1,-1},{-1,-1}};
int n;
vector <pair<pii,pii> > Point;
vector <pair<pii,pii> > T;

double dis(int i,int j)
{
	double res=sqrt((T[i].X-T[j].X)*(T[i].X-T[j].X)+(T[i].Y-T[j].Y)*(T[i].Y-T[j].Y));
	return res;
}

pair <pii,pii> Ans1,Ans2;
double Conq(int s,int e,int d)
{
	T.clear();
	int mid=(s+e)/2;
	for (int i=s;i<e;++i)
		if (Point[i].X + Point[mid].X<=d)
			T.PB(make_pair(pii(Point[i].Y,Point[i].X),pii(Point[i].ID,Point[i].COOR)));

	sort (T.begin(),T.end());
	int start=0;
	double h=INF;
	for (int i=0;i<SIZE(T);++i)
	{
		while (T[i].Y-T[start].Y > d)
			start++;
		for (int j=start;j<i;++j)
		{
			//h=min(dis(i,j),h);
			if (T[i].ID!=T[j].ID && h>dis(i,j))
			{
				h=dis(i,j);
				Ans1=T[i];
				Ans2=T[j];
			}
		}
	}
	return h;
}

double Solve(int s,int e)
{
	//cerr << s << ' ' << e << endl;
	if (s==e-1)
		return INF;
	int mid=(s+e)/2;
	double p,q;
	p=Solve(s,mid);
	q=Solve(mid,e);
	return min(min(p,q),Conq(s,e,min(p,q)));
}

int main()
{
	ifstream fin ("input.txt");
	ofstream fout ("output.txt");
	fin >> n;

	for (int i=0;i<n;++i)
	{
		int x,y;
		fin >> x >> y;
		for (int j=0;j<4;++j)
			Point.PB(make_pair(pii(x*mx[j][0],y*mx[j][1]),pii(i+1,j+1)));
	}
	//cerr << "EoO"<<endl;
	sort (Point.begin(),Point.end());
	//for (int i=0;i<SIZE(Point);++i)
	//	cerr << Point[i].X << ',' << Point[i].Y << "   ";
	//cerr << endl;
	Solve(0,n);
//	cerr << Ans1.X <<  ',' << Ans1.Y <<' ' << Ans2.X <<  ',' << Ans2.Y << endl;
	fout << Ans1.ID << ' ' << Ans1.COOR << ' ' << Ans2.ID << ' ';
	if (Ans2.COOR==1)
		fout << 4 << endl;
	if (Ans2.COOR==2)
		fout << 3 << endl;
	if (Ans2.COOR==3)
		fout << 2 << endl;
	if (Ans2.COOR==4)
		fout << 1 << endl;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstdio>
#include <fstream>
#define X first.first
#define Y first.second
#define ID second.first
#define COOR second.second
#define GI ({int i;scanf("%d",&i);i;})
#define PB(x) push_back(x)
#define SIZE(x) (int) x.size()
using namespace std;
const double INF=1000000000.0;
typedef pair <int,int> pii;
int mx[4][2]={{1,1},{-1,1},{1,-1},{-1,-1}};
int n;
vector <pair<pii,pii> > Point;
vector <pair<pii,pii> > T;

double dis(int i,int j)
{
	double res=sqrt((T[i].X-T[j].X)*(T[i].X-T[j].X)+(T[i].Y-T[j].Y)*(T[i].Y-T[j].Y));
	return res;
}

pair <pii,pii> Ans1,Ans2;
double Conq(int s,int e,double d)
{
	T.clear();
	int mid=(s+e)/2;
	for (int i=s;i<e;++i)
		if (max(Point[mid].X,Point[i].X)-min(Point[mid].X,Point[i].X)<=d)
			T.PB(make_pair(pii(Point[i].Y,Point[i].X),pii(Point[i].ID,Point[i].COOR)));
	sort (T.begin(),T.end());
	int start=0;
	double h=INF;
	for (int i=0;i<SIZE(T);++i)
	{
		while (T[i].X-T[start].X > d)
			start++;
		for (int j=start;j<i;++j)
		{
			if (T[i].ID!=T[j].ID && h>=dis(i,j))
			{
				h=dis(i,j);
				Ans1=T[i];
				Ans2=T[j];
			}
		}
	}
	return h;
}

double Solve(int s,int e)
{
	//cerr << s << ' ' << e << endl;
	if (s==e-1)
		return INF;
	int mid=(s+e)/2;
	double p,q;
	p=Solve(s,mid);
	q=Solve(mid,e);
	return min(min(p,q),Conq(s,e,min(p,q)));
}

int main()
{
	ifstream fin ("input.txt");
	ofstream fout ("output.txt");
	fin >> n;

	for (int i=0;i<n;++i)
	{
		int x,y;
		fin >> x >> y;
		for (int j=0;j<4;++j)
			Point.PB(make_pair(pii(x*mx[j][0],y*mx[j][1]),pii(i+1,j+1)));
	}
	//cerr << "EoO"<<endl;
	sort (Point.begin(),Point.end());
	//for (int i=0;i<SIZE(Point);++i)
	//	cerr << Point[i].X << ',' << Point[i].Y << "   ";
	//cerr << endl;
	Solve(0,Point.size());
	//	cerr << Ans1.X <<  ',' << Ans1.Y <<' ' << Ans2.X <<  ',' << Ans2.Y << endl;
	fout << Ans1.ID << ' ' << Ans1.COOR << ' ' << Ans2.ID << ' ';
	if (Ans2.COOR==1)
		fout << 4 << endl;
	if (Ans2.COOR==2)
		fout << 3 << endl;
	if (Ans2.COOR==3)
		fout << 2 << endl;
	if (Ans2.COOR==4)
		fout << 1 << endl;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstdio>
#include <fstream>
#define X first.first
#define Y first.second
#define ID second.first
#define COOR second.second
#define GI ({int i;scanf("%d",&i);i;})
#define PB(x) push_back(x)
#define SIZE(x) (int) x.size()
using namespace std;
const double INF=1000000000.0;
typedef pair <int,int> pii;
int mx[4][2]={{1,1},{-1,1},{1,-1},{-1,-1}};
int n;
vector <pair<pii,pii> > Point;
vector <pair<pii,pii> > T;

double dis(int i,int j)
{
	double res=sqrt((T[i].X-T[j].X)*(T[i].X-T[j].X)+(T[i].Y-T[j].Y)*(T[i].Y-T[j].Y));
	return res;
}

pair <pii,pii> Ans1,Ans2;
double MIN=INF;
double Conq(int s,int e,double d)
{
	T.clear();
	int mid=(s+e)/2;
	for (int i=s;i<e;++i)
		if (max(Point[mid].X,Point[i].X)-min(Point[mid].X,Point[i].X)<=d)
			T.PB(make_pair(pii(Point[i].Y,Point[i].X),pii(Point[i].ID,Point[i].COOR)));
	sort (T.begin(),T.end());
	int start=0;
	double h=INF;
	for (int i=0;i<SIZE(T);++i)
	{
		while (T[i].X-T[start].X > d)
			start++;
		for (int j=start;j<i;++j)
		{
			if (T[i].ID!=T[j].ID && h>=dis(i,j))
			{
				h=dis(i,j);
				if (h<=MIN)
				{
					Ans1=T[i];
					Ans2=T[j];
					MIN=h;
				}
			}
		}
	}
	return h;
}

double Solve(int s,int e)
{
	//cerr << s << ' ' << e << endl;
	if (s==e-1)
		return INF;
	int mid=(s+e)/2;
	double p,q;
	p=Solve(s,mid);
	q=Solve(mid,e);
	return min(min(p,q),Conq(s,e,min(p,q)));
}

int main()
{
	ifstream fin ("input.txt");
	ofstream fout ("output.txt");
	fin >> n;

	for (int i=0;i<n;++i)
	{
		int x,y;
		fin >> x >> y;
		for (int j=0;j<4;++j)
			Point.PB(make_pair(pii(x*mx[j][0],y*mx[j][1]),pii(i+1,j+1)));
	}
	//cerr << "EoO"<<endl;
	sort (Point.begin(),Point.end());
	//for (int i=0;i<SIZE(Point);++i)
	//	cerr << Point[i].X << ',' << Point[i].Y << "   ";
	//cerr << endl;
	Solve(0,Point.size());
	//	cerr << Ans1.X <<  ',' << Ans1.Y <<' ' << Ans2.X <<  ',' << Ans2.Y << endl;
	fout << Ans1.ID << ' ' << Ans1.COOR << ' ' << Ans2.ID << ' ';
	if (Ans2.COOR==1)
		fout << 4 << endl;
	if (Ans2.COOR==2)
		fout << 3 << endl;
	if (Ans2.COOR==3)
		fout << 2 << endl;
	if (Ans2.COOR==4)
		fout << 1 << endl;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstdio>

#define X first.first
#define Y first.second
#define ID second.first
#define COOR second.second
#define GI ({int i;scanf("%d",&i);i;})
#define PB(x) push_back(x)
#define SIZE(x) (int) x.size()
using namespace std;
const double INF=1000000000.0;
typedef pair <int,int> pii;
int mx[4][2]={{1,1},{-1,1},{1,-1},{-1,-1}};
int n;
vector <pair<pii,pii> > Point;
vector <pair<pii,pii> > T;

double dis(int i,int j)
{
	double res=sqrt((T[i].X-T[j].X)*(T[i].X-T[j].X)+(T[i].Y-T[j].Y)*(T[i].Y-T[j].Y));
	return res;
}

pair <pii,pii> Ans1,Ans2;
double Conq(int s,int e,int d)
{
	T.clear();
	int mid=(s+e)/2;
	for (int i=s;i<e;++i)
		if (Point[i].X + Point[mid].X<=d)
			T.PB(make_pair(pii(Point[i].Y,Point[i].X),pii(Point[i].ID,Point[i].COOR)));

	sort (T.begin(),T.end());
	int start=0;
	double h=INF;
	for (int i=0;i<SIZE(T);++i)
	{
		while (T[i].Y-T[start].Y > d)
			start++;
		for (int j=start;j<i;++j)
		{
			//h=min(dis(i,j),h);
			if (T[i].ID!=T[j].ID && h>dis(i,j))
			{
				h=dis(i,j);
				Ans1=T[i];
				Ans2=T[j];
			}
		}
	}
	return h;
}

double Solve(int s,int e)
{
	//cerr << s << ' ' << e << endl;
	if (s==e-1)
		return INF;
	int mid=(s+e)/2;
	double p,q;
	p=Solve(s,mid);
	q=Solve(mid,e);
	return min(min(p,q),Conq(s,e,min(p,q)));
}

int main()
{
	cin >> n;
	for (int i=0;i<n;++i)
	{
		int x=GI,y=GI;
		for (int j=0;j<4;++j)
			Point.PB(make_pair(pii(x*mx[j][0],y*mx[j][1]),pii(i+1,j+1)));
	}
	//cerr << "EoO"<<endl;
	sort (Point.begin(),Point.end());
	//for (int i=0;i<SIZE(Point);++i)
	//	cerr << Point[i].X << ',' << Point[i].Y << "   ";
	//cerr << endl;
	Solve(0,n);
//	cerr << Ans1.X <<  ',' << Ans1.Y <<' ' << Ans2.X <<  ',' << Ans2.Y << endl;
	cout << Ans1.ID << ' ' << Ans1.COOR << ' ' << Ans2.ID << ' ';
	if (Ans2.COOR==1)
		cout << 4 << endl;
	if (Ans2.COOR==2)
		cout << 3 << endl;
	if (Ans2.COOR==3)
		cout << 2 << endl;
	if (Ans2.COOR==4)
		cout << 1 << endl;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>

#define X first.first
#define Y first.second
#define ID second.first
#define COOR second.second
#define GI ({int i;scanf("%d",&i);i;})
#define PB(x) push_back(x)
#define SIZE(x) (int) x.size()
using namespace std;
const double INF=1000000000.0;
typedef pair <int,int> pii;
int mx[4][2]={{1,1},{-1,1},{1,-1},{-1,-1}};
int n;
vector <pair<pii,pii> > Point;
vector <pair<pii,pii> > T;

double dis(int i,int j)
{
	double res=sqrt((T[i].X-T[j].X)*(T[i].X-T[j].X)+(T[i].Y-T[j].Y)*(T[i].Y-T[j].Y));
	return res;
}

pair <pii,pii> Ans1,Ans2;
double Conq(int s,int e,int d)
{
	T.clear();
	int mid=(s+e)/2;
	for (int i=s;i<e;++i)
		if (Point[i].X + Point[mid].X<=d)
			T.PB(make_pair(pii(Point[i].Y,Point[i].X),pii(Point[i].ID,Point[i].COOR)));

	sort (T.begin(),T.end());
	int start=0;
	double h=INF;
	for (int i=0;i<SIZE(T);++i)
	{
		while (T[i].Y-T[start].Y > d)
			start++;
		for (int j=start;j<i;++j)
		{
			//h=min(dis(i,j),h);
			if (T[i].ID!=T[j].ID && h>dis(i,j))
			{
				h=dis(i,j);
				Ans1=T[i];
				Ans2=T[j];
			}
		}
	}
	return h;
}

double Solve(int s,int e)
{
	//cerr << s << ' ' << e << endl;
	if (s==e-1)
		return INF;
	int mid=(s+e)/2;
	double p,q;
	p=Solve(s,mid);
	q=Solve(mid,e);
	return min(min(p,q),Conq(s,e,min(p,q)));
}

int main()
{
	cin >> n;
	for (int i=0;i<n;++i)
	{
		int x=GI,y=GI;
		for (int j=0;j<4;++j)
			Point.PB(make_pair(pii(x*mx[j][0],y*mx[j][1]),pii(i+1,j+1)));
	}
	//cerr << "EoO"<<endl;
	sort (Point.begin(),Point.end());
	//for (int i=0;i<SIZE(Point);++i)
	//	cerr << Point[i].X << ',' << Point[i].Y << "   ";
	//cerr << endl;
	Solve(0,n);
//	cerr << Ans1.X <<  ',' << Ans1.Y <<' ' << Ans2.X <<  ',' << Ans2.Y << endl;
	cout << Ans1.ID << ' ' << Ans1.COOR << ' ' << Ans2.ID << ' ';
	if (Ans2.COOR==1)
		cout << 4 << endl;
	if (Ans2.COOR==2)
		cout << 3 << endl;
	if (Ans2.COOR==3)
		cout << 2 << endl;
	if (Ans2.COOR==4)
		cout << 1 << endl;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstdio>
#include <fstream>
#define X first.first
#define Y first.second
#define ID second.first
#define COOR second.second
#define GI ({int i;scanf("%d",&i);i;})
#define PB(x) push_back(x)
#define SIZE(x) (int) x.size()
using namespace std;
const double INF=1000000000.0;
typedef pair <int,int> pii;
int mx[4][2]={{1,1},{-1,1},{1,-1},{-1,-1}};
int n;
vector <pair<pii,pii> > Point;
vector <pair<pii,pii> > T;

double dis(int i,int j)
{
	double res=sqrt((T[i].X-T[j].X)*(T[i].X-T[j].X)+(T[i].Y-T[j].Y)*(T[i].Y-T[j].Y));
	return res;
}

pair <pii,pii> Ans1,Ans2;
double MIN=INF;
double Conq(int s,int e,double d)
{
	T.clear();
	int mid=(s+e)/2;
	for (int i=s;i<e;++i)
		if (max(Point[mid].X,Point[i].X)-min(Point[mid].X,Point[i].X)<=d)
			T.PB(make_pair(pii(Point[i].Y,Point[i].X),pii(Point[i].ID,Point[i].COOR)));
	sort (T.begin(),T.end());
	int start=0;
	double h=INF;
	for (int i=0;i<SIZE(T);++i)
	{
		while (T[i].X-T[start].X > d)
			start++;
		for (int j=start;j<i;++j)
		{
			if (T[i].ID!=T[j].ID && h>=dis(i,j))
			{
				h=dis(i,j);
				if (h<=MIN)
				{
					Ans1=T[i];
					Ans2=T[j];
					MIN=h;
				}
			}
		}
	}
	return h;
}

double Solve(int s,int e)
{
	//cerr << s << ' ' << e << endl;
	if (s==e-1)
		return INF;
	int mid=(s+e)/2;
	double p,q;
	p=Solve(s,mid);
	q=Solve(mid,e);
	return min(min(p,q),Conq(s,e,min(p,q)));
}

int main()
{
	ios ::sync_with_stdio(0);
	ifstream fin ("input.txt");
	ofstream fout ("output.txt");
	fin >> n;

	for (int i=0;i<n;++i)
	{
		int x,y;
		fin >> x >> y;
		for (int j=0;j<4;++j)
			Point.PB(make_pair(pii(x*mx[j][0],y*mx[j][1]),pii(i+1,j+1)));
	}
	//cerr << "EoO"<<endl;
	sort (Point.begin(),Point.end());
	//for (int i=0;i<SIZE(Point);++i)
	//	cerr << Point[i].X << ',' << Point[i].Y << "   ";
	//cerr << endl;
	Solve(0,Point.size());
	//	cerr << Ans1.X <<  ',' << Ans1.Y <<' ' << Ans2.X <<  ',' << Ans2.Y << endl;
	fout << Ans1.ID << ' ' << Ans1.COOR << ' ' << Ans2.ID << ' ';
	if (Ans2.COOR==1)
		fout << 4 << endl;
	if (Ans2.COOR==2)
		fout << 3 << endl;
	if (Ans2.COOR==3)
		fout << 2 << endl;
	if (Ans2.COOR==4)
		fout << 1 << endl;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define SQR(x) ((x) * (x))
using namespace std;
const int N_MAX = 100010;
struct Point{
	int x, y, k[2];
	int getPosIdx(){
		if(!k[0] && !k[1])
			return 4;
		else if(!k[0] && k[1])
			return 2;
		else if(k[0] && !k[1])
			return 3;
		else
			return 1;
	}
	int getNegIdx(){
		if(!k[0] && !k[1])
			return 1;
		else if(!k[0] && k[1])
			return 3;
		else if(k[0] && !k[1])
			return 2;
		else
			return 4;
	}
} p[N_MAX];
int X[N_MAX];
struct Info{
	int i, j;
   	double len;
	Info(int _i, int _j, double _len):
		i(_i), j(_j), len(_len){}
	bool operator< (const Info &t) const{
		return len < t.len;
	}
};
int N;

bool cmpOnX(int a, int b){
	return p[a].x < p[b].x;
}

bool cmpOnY(int a, int b){
	return p[a].y < p[b].y;
}

Info getDist(int i, int j){
	return Info(i, j, sqrt(SQR(p[i].x - p[j].x) + SQR(p[i].y - p[j].y)));
}

Info solve(int l, int r){
	if(r - l + 1 <= 3){
		Info res(-1, -1, 10e100);
		for(int i = l; i <= r; i ++)
			for(int j = i + 1; j <= r; j ++)
				res = min(res, getDist(X[i], X[j]));
		return res;
	}
	int mid = (l + r) / 2;
	Info left = solve(l, mid),
		 right = solve(mid, r);
	double delta = 2 * min(left.len, right.len);
	static int tmp[N_MAX];
	int tmpCnt = 0;
	for(int i = l; i <= r; i ++)
		if(mid - delta < p[X[i]].x && p[X[i]].x < mid + delta)
			tmp[tmpCnt ++] = X[i];
	sort(tmp, tmp + tmpCnt, cmpOnY);
	Info res = min(left, right);
	for(int i = 0; i < tmpCnt - 1; i ++)
		for(int j = i + 1; j < tmpCnt && j - i + 1 <= 8; j ++)
			res = min(res, getDist(tmp[i], tmp[j]));
	return res;
}

int main(){
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	scanf("%d", &N);
	for(int i = 1; i <= N; i ++){
		scanf("%d%d", &p[i].x, &p[i].y);
		p[i].k[0] = p[i].x < 0, p[i].k[1] = p[i].y < 0;
		p[i].x = abs(p[i].x), p[i].y = abs(p[i].y);
	}
	for(int i = 1; i <= N; i ++)
		X[i] = i;
	sort(X + 1, X + N + 1, cmpOnX);
	Info res = solve(1, N);
	printf("%d %d %d %d\n", res.i, p[res.i].getPosIdx(), res.j, p[res.j].getNegIdx());
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define SQR(x) ((x) * (x))
using namespace std;
const int N_MAX = 100010;
struct Point{
	int x, y, k[2];
	int getPosIdx(){
		if(!k[0] && !k[1])
			return 4;
		else if(!k[0] && k[1])
			return 2;
		else if(k[0] && !k[1])
			return 3;
		else
			return 1;
	}
	int getNegIdx(){
		if(!k[0] && !k[1])
			return 1;
		else if(!k[0] && k[1])
			return 3;
		else if(k[0] && !k[1])
			return 2;
		else
			return 4;
	}
} p[N_MAX];
int X[N_MAX];
struct Info{
	int i, j;
   	double len;
	Info(int _i, int _j, double _len):
		i(_i), j(_j), len(_len){}
	bool operator< (const Info &t) const{
		return len < t.len;
	}
};
int N;

bool cmpOnX(int a, int b){
	return p[a].x < p[b].x;
}

bool cmpOnY(int a, int b){
	return p[a].y < p[b].y;
}

Info getDist(int i, int j){
	return Info(i, j, sqrt(SQR(p[i].x - p[j].x) + SQR(p[i].y - p[j].y)));
}

Info solve(int l, int r){
	if(r - l + 1 <= 3){
		Info res(-1, -1, 10e100);
		for(int i = l; i <= r; i ++)
			for(int j = i + 1; j <= r; j ++)
				res = min(res, getDist(X[i], X[j]));
		return res;
	}
	int mid = (l + r) / 2;
	Info left = solve(l, mid),
		 right = solve(mid + 1, r);
	double delta = 2 * min(left.len, right.len);
	static int tmp[N_MAX];
	int tmpCnt = 0;
	for(int i = l; i <= r; i ++)
		if(p[X[mid]].x - delta < p[X[i]].x && p[X[i]].x < p[X[mid]].x + delta)
			tmp[tmpCnt ++] = X[i];
	sort(tmp, tmp + tmpCnt, cmpOnY);
	Info res = min(left, right);
	for(int i = 0; i < tmpCnt - 1; i ++)
		for(int j = i + 1; j < tmpCnt && j - i + 1 <= 8; j ++)
			res = min(res, getDist(tmp[i], tmp[j]));
	return res;
}

int main(){
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	scanf("%d", &N);
	for(int i = 1; i <= N; i ++){
		scanf("%d%d", &p[i].x, &p[i].y);
		p[i].k[0] = p[i].x < 0, p[i].k[1] = p[i].y < 0;
		p[i].x = abs(p[i].x), p[i].y = abs(p[i].y);
	}
	for(int i = 1; i <= N; i ++)
		X[i] = i;
	sort(X + 1, X + N + 1, cmpOnX);
	Info res = solve(1, N);
	printf("%d %d %d %d\n", res.i, p[res.i].getPosIdx(), res.j, p[res.j].getNegIdx());
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define SQR(x) ((x) * (x))
using namespace std;
const int N_MAX = 100010;
struct Point{
	int x, y, k[2];
	int getIdx(){
		return k[1] * 2 + k[0] + 1;
	}
} p[N_MAX];
int X[N_MAX];
struct Info{
	int i, j;
   	double len;
	Info(int _i, int _j, double _len):
		i(_i), j(_j), len(_len){}
	bool operator< (const Info &t) const{
		return len < t.len;
	}
};
int N;

bool cmpOnX(int a, int b){
	return p[a].x < p[b].x;
}

bool cmpOnY(int a, int b){
	return p[a].y < p[b].y;
}

Info getDist(int i, int j){
	return Info(i, j, sqrt(SQR(p[i].x - p[j].x) + SQR(p[i].y - p[j].y)));
}

Info solve(int l, int r){
	if(r - l + 1 <= 3){
		Info res(-1, -1, 10e100);
		for(int i = l; i <= r; i ++)
			for(int j = i + 1; j <= r; j ++)
				res = min(res, getDist(X[i], X[j]));
		return res;
	}
	int mid = (l + r) / 2;
	Info left = solve(l, mid),
		 right = solve(mid, r);
	double delta = 2 * min(left.len, right.len);
	static int tmp[N_MAX];
	int tmpCnt = 0;
	for(int i = l; i <= r; i ++)
		if(mid - delta < p[X[i]].x && p[X[i]].x < mid + delta)
			tmp[tmpCnt ++] = X[i];
	sort(tmp, tmp + tmpCnt, cmpOnY);
	Info res = min(left, right);
	for(int i = 0; i < tmpCnt - 1; i ++)
		for(int j = i + 1; j < tmpCnt && j - i + 1 <= 8; j ++)
			res = min(res, getDist(tmp[i], tmp[j]));
	return res;
}

int main(){
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	scanf("%d", &N);
	for(int i = 1; i <= N; i ++){
		scanf("%d%d", &p[i].x, &p[i].y);
		p[i].k[0] = p[i].x < 0, p[i].k[1] = p[i].y < 0;
		p[i].x = abs(p[i].x), p[i].y = abs(p[i].y);
	}
	for(int i = 1; i <= N; i ++)
		X[i] = i;
	sort(X + 1, X + N + 1, cmpOnX);
	Info res = solve(1, N);
	printf("%d %d %d %d\n", res.i, p[res.i].getIdx(), res.j, p[res.j].getIdx());
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define SQR(x) ((x) * (x))
using namespace std;
const int N_MAX = 100010;
struct Point{
	int x, y, k[2];
	int getPosIdx(){
		if(!k[0] && !k[1])
			return 4;
		else if(!k[0] && k[1])
			return 2;
		else if(k[0] && !k[1])
			return 3;
		else
			return 1;
	}
	int getNegIdx(){
		if(!k[0] && !k[1])
			return 1;
		else if(!k[0] && k[1])
			return 3;
		else if(k[0] && !k[1])
			return 2;
		else
			return 4;
	}
} p[N_MAX];
int X[N_MAX];
struct Info{
	int i, j;
   	double len;
	Info(int _i, int _j, double _len):
		i(_i), j(_j), len(_len){}
	bool operator< (const Info &t) const{
		return len < t.len;
	}
};
int N;

bool cmpOnX(int a, int b){
	return p[a].x < p[b].x;
}

bool cmpOnY(int a, int b){
	return p[a].y < p[b].y;
}

Info getDist(int i, int j){
	return Info(i, j, sqrt(SQR(p[i].x - p[j].x) + SQR(p[i].y - p[j].y)));
}

Info solve(int l, int r){
	if(r - l + 1 <= 3){
		Info res(-1, -1, 10e100);
		for(int i = l; i <= r; i ++)
			for(int j = i + 1; j <= r; j ++)
				res = min(res, getDist(X[i], X[j]));
		return res;
	}
	int mid = (l + r) / 2;
	Info left = solve(l, mid),
		 right = solve(mid + 1, r);
	double delta = 2 * min(left.len, right.len);
	static int tmp[N_MAX];
	int tmpCnt = 0;
	for(int i = l; i <= r; i ++)
		if(mid - delta <= p[X[i]].x && p[X[i]].x <= mid + delta)
			tmp[tmpCnt ++] = X[i];
	sort(tmp, tmp + tmpCnt, cmpOnY);
	Info res = min(left, right);
	for(int i = 0; i < tmpCnt - 1; i ++)
		for(int j = i + 1; j < tmpCnt && j - i + 1 <= 8; j ++)
			res = min(res, getDist(tmp[i], tmp[j]));
	return res;
}

int main(){
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	scanf("%d", &N);
	for(int i = 1; i <= N; i ++){
		scanf("%d%d", &p[i].x, &p[i].y);
		p[i].k[0] = p[i].x < 0, p[i].k[1] = p[i].y < 0;
		p[i].x = abs(p[i].x), p[i].y = abs(p[i].y);
	}
	for(int i = 1; i <= N; i ++)
		X[i] = i;
	sort(X + 1, X + N + 1, cmpOnX);
	Info res = solve(1, N);
	printf("%d %d %d %d\n", res.i, p[res.i].getPosIdx(), res.j, p[res.j].getNegIdx());
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define SQR(x) ((x) * (x))
using namespace std;
const int N_MAX = 100010;
struct Point{
	int x, y, k[2];
	int getPosIdx(){
		if(!k[0] && !k[1])
			return 4;
		else if(!k[0] && k[1])
			return 2;
		else if(k[0] && !k[1])
			return 3;
		else
			return 1;
	}
	int getNegIdx(){
		if(!k[0] && !k[1])
			return 1;
		else if(!k[0] && k[1])
			return 3;
		else if(k[0] && !k[1])
			return 2;
		else
			return 4;
	}
} p[N_MAX];
int X[N_MAX];
struct Info{
	int i, j;
   	double len;
	Info(int _i, int _j, double _len):
		i(_i), j(_j), len(_len){}
	bool operator< (const Info &t) const{
		return len < t.len;
	}
};
int N;

bool cmpOnX(int a, int b){
	return p[a].x < p[b].x;
}

bool cmpOnY(int a, int b){
	return p[a].y < p[b].y;
}

Info getDist(int i, int j){
	return Info(i, j, sqrt(SQR(p[i].x - p[j].x) + SQR(p[i].y - p[j].y)));
}

Info solve(int l, int r){
	if(r - l + 1 <= 3){
		Info res(-1, -1, 10e100);
		for(int i = l; i <= r; i ++)
			for(int j = i + 1; j <= r; j ++)
				res = min(res, getDist(X[i], X[j]));
		return res;
	}
	int mid = (l + r) / 2;
	Info left = solve(l, mid),
		 right = solve(mid, r);
	double delta = 2 * min(left.len, right.len);
	static int tmp[N_MAX];
	int tmpCnt = 0;
	for(int i = l; i <= r; i ++)
		if(mid - delta <= p[X[i]].x && p[X[i]].x <= mid + delta)
			tmp[tmpCnt ++] = X[i];
	sort(tmp, tmp + tmpCnt, cmpOnY);
	Info res = min(left, right);
	for(int i = 0; i < tmpCnt - 1; i ++)
		for(int j = i + 1; j < tmpCnt && j - i + 1 <= 8; j ++)
			res = min(res, getDist(tmp[i], tmp[j]));
	return res;
}

int main(){
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	scanf("%d", &N);
	for(int i = 1; i <= N; i ++){
		scanf("%d%d", &p[i].x, &p[i].y);
		p[i].k[0] = p[i].x < 0, p[i].k[1] = p[i].y < 0;
		p[i].x = abs(p[i].x), p[i].y = abs(p[i].y);
	}
	for(int i = 1; i <= N; i ++)
		X[i] = i;
	sort(X + 1, X + N + 1, cmpOnX);
	Info res = solve(1, N);
	printf("%d %d %d %d\n", res.i, p[res.i].getPosIdx(), res.j, p[res.j].getNegIdx());
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define SQR(x) ((x) * (x))
using namespace std;
const int N_MAX = 100010;
struct Point{
	int x, y, k[2];
	int getPosIdx(){
		if(!k[0] && !k[1])
			return 4;
		else if(!k[0] && k[1])
			return 2;
		else if(k[0] && !k[1])
			return 3;
		else
			return 1;
	}
	int getNegIdx(){
		if(!k[0] && !k[1])
			return 1;
		else if(!k[0] && k[1])
			return 3;
		else if(k[0] && !k[1])
			return 2;
		else
			return 4;
	}
} p[N_MAX];
int X[N_MAX];
struct Info{
	int i, j;
   	double len;
	Info(int _i, int _j, double _len):
		i(_i), j(_j), len(_len){}
	bool operator< (const Info &t) const{
		return len < t.len;
	}
};
int N;

bool cmpOnX(int a, int b){
	return p[a].x < p[b].x;
}

bool cmpOnY(int a, int b){
	return p[a].y < p[b].y;
}

Info getDist(int i, int j){
	return Info(i, j, sqrt(SQR(p[i].x - p[j].x) + SQR(p[i].y - p[j].y)));
}

Info solve(int l, int r){
	if(r - l + 1 <= 10){
		Info res(-1, -1, 10e100);
		for(int i = l; i <= r; i ++)
			for(int j = i + 1; j <= r; j ++)
				res = min(res, getDist(X[i], X[j]));
		return res;
	}
	int mid = (l + r) / 2;
	Info left = solve(l, mid),
		 right = solve(mid, r);
	double delta = 2 * min(left.len, right.len);
	static int tmp[N_MAX];
	int tmpCnt = 0;
	for(int i = l; i <= r; i ++)
		if(mid - delta < p[X[i]].x && p[X[i]].x < mid + delta)
			tmp[tmpCnt ++] = X[i];
	sort(tmp, tmp + tmpCnt, cmpOnY);
	Info res = min(left, right);
	for(int i = 0; i < tmpCnt - 1; i ++)
		for(int j = i + 1; j < tmpCnt && j - i + 1 <= 8; j ++)
			res = min(res, getDist(tmp[i], tmp[j]));
	return res;
}

int main(){
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	scanf("%d", &N);
	for(int i = 1; i <= N; i ++){
		scanf("%d%d", &p[i].x, &p[i].y);
		p[i].k[0] = p[i].x < 0, p[i].k[1] = p[i].y < 0;
		p[i].x = abs(p[i].x), p[i].y = abs(p[i].y);
	}
	for(int i = 1; i <= N; i ++)
		X[i] = i;
	sort(X + 1, X + N + 1, cmpOnX);
	Info res = solve(1, N);
	printf("%d %d %d %d\n", res.i, p[res.i].getPosIdx(), res.j, p[res.j].getNegIdx());
}


/*******************************************************************************************************************************************
* File Name   : j.cpp
* Development : Wed 19 Oct 2011 09:40:46 PM IST
* Author      : Xeronix
*******************************************************************************************************************************************/

#include <iostream>
#include <cstdio>
#include <vector>
#include <math.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <string.h>
#include <cstdlib>
#include <sstream>
#include <stack>
#include <queue>
#include <numeric>
#include <utility>
#include <cctype>
#include <list>
#include <limits.h>
#include <signal.h>
#include <time.h>
#include <map>
#include <set>
#include <float.h>

#define TR(c, i) for ( typeof((c).begin()) i = (c).begin(); i != (c).end(); i++ )
#define FOR(i, a, b) for ( i = a; i <= b; i++ )
#define ROF(i, a, b) for ( i = a; i >= b; i-- )
#define ALL(v) (v).begin(), (v).end()
#define SORT(v) sort( ALL(v) )
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#define ABS(a) ((a) < (0) ? (a)*(-1) : (a))
#define SWAP(a, b) typeof(a) T; T=a; a=b; b=T;
#define SET(x,a) memset(x,a,sizeof(x))

//#define LIM
#ifdef LIM
	int S, D, Y;
	char *inp, *out, *ipos, *opos, DIG[30];
	#define FRMI inp=( char * )malloc( LIM*sizeof( char ) );fread_unlocked( inp,1,LIM,stdin );ipos=inp;
	#define FWM out=( char * )malloc( LIM*sizeof( char ) );opos=out;
	#define FWO fwrite_unlocked( out,opos-out,1,stdout );
        #define GETI(n) n=0;while(*ipos<33){ipos++;}if(*ipos=='-'){S=-1;ipos++;}else{S=1;}while(*ipos>='0'){n=10*n+(*ipos-'0');ipos++;}n*=S;
	#define PUTI(n) D=0;if(n<0){*opos++='-';n*=-1;}if(!n)*opos++='0';else{while(n){Y=n/10;DIG[D++]=n-Y*10+'0';n=Y;}\
	while(D--)*opos++=DIG[D];}
	#define PUTC(c) *opos++=c;
#endif

#define SQ(x) (x)*(x)
#define DIST( a,b ) ( SQ(a.x-b.x) + SQ(a.y-b.y) )
#define DISTI( a,b,c,d ) ( SQ(a+c) + SQ(b+d) )

using namespace std;
using namespace __gnu_cxx;

struct point {
	int x, y;
	int v;
	int id;
};

bool comparex( point p, point q )
{
	return p.x < q.x;
}

bool comparey( point p, point q )
{
	return p.y < q.y;
}

point min_p1, min_p2;
int min_dist = INT_MAX;

void closest_pair( point *px, point *py, int n )
{
	int i, j;
	int d;

	if( n <= 3 ) {
		if( n >= 2 ) {
			FOR( i,0,n-2 ) {
				FOR( j,i+1,n-1 ) {
					if( px[i].id != px[j].id && ( d = DIST( px[i], px[j] ) ) < min_dist ) {
						min_dist = d;
						min_p1 = px[i];
						min_p2 = px[j];
					}
				}
			}
		}
	} else {
		int mid, divider;

		mid = n >> 1;

		point pxl[mid+1], pxr[mid+1];
		point pyl[mid+1], pyr[mid+1];

		int pyl_len, pyr_len;

		FOR( i,0,mid ) {
			pxl[i] = px[i];
			if( mid+i+1 < n ) {
				pxr[i] = px[mid+i+1];
			}
		}

		divider = px[mid].x;
		pyl_len = pyr_len = 0;

		FOR( i,0,n-1 ) {
			if( py[i].x <= divider ) {
				pyl[pyl_len++] = py[i];
			} else {
				pyr[pyr_len++] = py[i];
			}
		}

		closest_pair( pxl, pyl, mid );
		closest_pair( pxr, pyr, n-mid-1 );

		point pyd[n];
		int pyd_len = 0;

		FOR( i,0,n-1 ) {
			if( ABS( py[i].x-divider ) <= sqrt( min_dist ) ) {
				pyd[pyd_len++] = py[i];
			}
		}

		if( pyd_len > 1 ) {
			FOR( i,0,pyd_len-1 ) {
				for( j=i+1; j <= i+7 && j < pyd_len; j++ ) {
					if( pyd[i].id != pyd[j].id && ( d = DIST( pyd[i], pyd[j] ) ) <= min_dist ) {
						min_dist = d;
						min_p1 = pyd[i];
						min_p2 = pyd[j];
					}
				}
			}
		}
	}
}

inline int version( int a, int b, int x, int y )
{
	if( a == x && b == y ) {
		return 1;
	} else if( a == -x && b == y ) {
		return 2;
	} else if( a == x && b == -y ) {
		return 3;
	} else {
		return 4;
	}
}

int main()
{
	int i, j;
	int n, m, a, b;
	point pt;

	freopen( "input.txt", "r", stdin );
	freopen( "output.txt", "w", stdout );

	scanf( "%d", &n );

//	m = n << 2;
	point px[n], py[n],  temp[n];;

	j = 0;

	FOR( i,0,n-1 ) {
		scanf( "%d%d", &a, &b );
		temp[i].x = a;
		temp[i].y = b;
		temp[i].id = i+1;
		pt.x = ABS(a);
		pt.y = ABS(b);
		pt.id = i+1;
		//	a = ABS(a); b = ABS(b);
	/*	pt.id = i+1;
		pt.x = a; pt.y = b; pt.v = 1; px[j] = py[j] = pt; j++;
		pt.x = a*-1; pt.y = b; pt.v = 2; px[j] = py[j] = pt; j++;
		pt.x = a; pt.y = b*-1; pt.v = 3; px[j] = py[j] = pt; j++;
		pt.x = a*-1; pt.y = b*-1; pt.v = 4; px[j] = py[j] = pt; j++;
		*/
//		pt.v = version( a, b, pt.x, pt.y );
		px[j] = py[j] = pt;
		j++;
	}

	sort( px, px+j, comparex );
	sort( py, py+j, comparey );

	closest_pair( px, py, n );

	int ans[4];

	ans[0] = min_p1.x;
	ans[1] = min_p1.y;
	ans[2] = min_p2.x;
	ans[3] = min_p2.y;

	int d, ver1, ver2;

	ver1 = 1;
	ver2 = 1;

	min_dist = DISTI( min_p1.x, min_p1.y, min_p2.x, min_p2.y );

	FOR( i,0,15 ) {
		FOR( j,0,3 ) {
			if ( i & (1<<j) ) {
				ans[j] = ABS(ans[j])*-1;
			}
		}

		if( ( d = DISTI( ans[0], ans[1], ans[2], ans[3] ) ) < min_dist ) {
			min_dist = d;
			ver1 = version( ans[0], ans[1], temp[min_p1.id].x, temp[min_p1.id].y );
			ver2 = version( ans[2], ans[3], temp[min_p2.id].x, temp[min_p2.id].y );
		}
	}

//	cout << min_dist << endl;
	printf( "%d %d %d %d\n", min_p1.id, ver1, min_p2.id, ver2 );

	return 0;
}


/*******************************************************************************************************************************************
* File Name   : j.cpp
* Development : Wed 19 Oct 2011 09:40:46 PM IST
* Author      : Xeronix
*******************************************************************************************************************************************/

#include <iostream>
#include <cstdio>
#include <vector>
#include <math.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <string.h>
#include <cstdlib>
#include <sstream>
#include <stack>
#include <queue>
#include <numeric>
#include <utility>
#include <cctype>
#include <list>
#include <limits.h>
#include <signal.h>
#include <time.h>
#include <map>
#include <set>
#include <float.h>

#define TR(c, i) for ( typeof((c).begin()) i = (c).begin(); i != (c).end(); i++ )
#define FOR(i, a, b) for ( i = a; i <= b; i++ )
#define ROF(i, a, b) for ( i = a; i >= b; i-- )
#define ALL(v) (v).begin(), (v).end()
#define SORT(v) sort( ALL(v) )
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#define ABS(a) ((a) < (0) ? (a)*(-1) : (a))
#define SWAP(a, b) typeof(a) T; T=a; a=b; b=T;
#define SET(x,a) memset(x,a,sizeof(x))

//#define LIM
#ifdef LIM
	int S, D, Y;
	char *inp, *out, *ipos, *opos, DIG[30];
	#define FRMI inp=( char * )malloc( LIM*sizeof( char ) );fread_unlocked( inp,1,LIM,stdin );ipos=inp;
	#define FWM out=( char * )malloc( LIM*sizeof( char ) );opos=out;
	#define FWO fwrite_unlocked( out,opos-out,1,stdout );
        #define GETI(n) n=0;while(*ipos<33){ipos++;}if(*ipos=='-'){S=-1;ipos++;}else{S=1;}while(*ipos>='0'){n=10*n+(*ipos-'0');ipos++;}n*=S;
	#define PUTI(n) D=0;if(n<0){*opos++='-';n*=-1;}if(!n)*opos++='0';else{while(n){Y=n/10;DIG[D++]=n-Y*10+'0';n=Y;}\
	while(D--)*opos++=DIG[D];}
	#define PUTC(c) *opos++=c;
#endif

#define SQ(x) (x)*(x)
#define DIST( a,b ) ( SQ(a.x-b.x) + SQ(a.y-b.y) )
#define DISTI( a,b,c,d ) ( SQ(a+c) + SQ(b+d) )

using namespace std;
using namespace __gnu_cxx;

struct point {
	int x, y;
	int id;
};

bool comparex( point p, point q )
{
	return p.x < q.x;
}

bool comparey( point p, point q )
{
	return p.y < q.y;
}

point min_p1, min_p2;
int min_dist = INT_MAX;

void closest_pair( point *px, point *py, int n )
{
	int i, j;
	int d;

	if( n <= 3 ) {
		if( n >= 2 ) {
			FOR( i,0,n-2 ) {
				FOR( j,i+1,n-1 ) {
					if( px[i].id != px[j].id && ( d = DIST( px[i], px[j] ) ) < min_dist ) {
						min_dist = d;
						min_p1 = px[i];
						min_p2 = px[j];
					}
				}
			}
		}
	} else {
		int mid, divider;

		mid = n >> 1;

		point pxl[mid+1], pxr[mid+1];
		point pyl[mid+1], pyr[mid+1];
/*		point *pxl, *pxr;
		point *pyl, *pyr;
		pxl = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pxr = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pyl = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pyr = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
*/
		int pyl_len, pyr_len;

		FOR( i,0,mid ) {
			pxl[i] = px[i];
			if( mid+i+1 < n ) {
				pxr[i] = px[mid+i+1];
			}
		}

		divider = px[mid].x;
		pyl_len = pyr_len = 0;

		FOR( i,0,n-1 ) {
			if( py[i].x <= divider ) {
				pyl[pyl_len++] = py[i];
			} else {
				pyr[pyr_len++] = py[i];
			}
		}

		closest_pair( pxl, pyl, mid );
		closest_pair( pxr, pyr, n-mid-1 );

		point *pyd;
		pyd = ( struct point * )malloc( n*sizeof( struct point ) );
		int pyd_len = 0;

		FOR( i,0,n-1 ) {
			if( ABS( py[i].x-divider ) <= sqrt( min_dist ) ) {
				pyd[pyd_len++] = py[i];
			}
		}

		if( pyd_len > 1 ) {
			FOR( i,0,pyd_len-1 ) {
				for( j=i+1; j <= i+7 && j < pyd_len; j++ ) {
					if( pyd[i].id != pyd[j].id && ( d = DIST( pyd[i], pyd[j] ) ) <= min_dist ) {
						min_dist = d;
						min_p1 = pyd[i];
						min_p2 = pyd[j];
					}
				}
			}
		}

//		free( pyd );
	}
}

inline int version( int a, int b, int x, int y )
{
	if( a == x && b == y ) {
		return 1;
	} else if( a == -x && b == y ) {
		return 2;
	} else if( a == x && b == -y ) {
		return 3;
	} else {
		return 4;
	}
}

int main()
{
	int i, j;
	int n, m, a, b;
	point pt;

	freopen( "input.txt", "r", stdin );
	freopen( "output.txt", "w", stdout );

	scanf( "%d", &n );

//	m = n << 2;
//	point px[n], py[n],  temp[n];;

	point *px, *py, *temp;

	px = ( struct point * )malloc( n*sizeof( struct point ) );
	py = ( struct point * )malloc( n*sizeof( struct point ) );
	temp = ( struct point * )malloc( n*sizeof( struct point ) );

	j = 0;

	FOR( i,0,n-1 ) {
		scanf( "%d%d", &a, &b );
		temp[i].x = a;
		temp[i].y = b;
		temp[i].id = i+1;
		pt.x = ABS(a);
		pt.y = ABS(b);
		pt.id = i+1;
		//	a = ABS(a); b = ABS(b);
	/*	pt.id = i+1;
		pt.x = a; pt.y = b; pt.v = 1; px[j] = py[j] = pt; j++;
		pt.x = a*-1; pt.y = b; pt.v = 2; px[j] = py[j] = pt; j++;
		pt.x = a; pt.y = b*-1; pt.v = 3; px[j] = py[j] = pt; j++;
		pt.x = a*-1; pt.y = b*-1; pt.v = 4; px[j] = py[j] = pt; j++;
		*/
//		pt.v = version( a, b, pt.x, pt.y );
		px[j] = py[j] = pt;
		j++;
	}

	sort( px, px+j, comparex );
	sort( py, py+j, comparey );

	closest_pair( px, py, n );

	int ans[4];

	ans[0] = min_p1.x;
	ans[1] = min_p1.y;
	ans[2] = min_p2.x;
	ans[3] = min_p2.y;

	int d, ver1, ver2;

	ver1 = 1;
	ver2 = 1;

	min_dist = DISTI( min_p1.x, min_p1.y, min_p2.x, min_p2.y );

	FOR( i,0,15 ) {
		FOR( j,0,3 ) {
			if ( i & (1<<j) ) {
				ans[j] = ABS(ans[j])*-1;
			}
		}

		if( ( d = DISTI( ans[0], ans[1], ans[2], ans[3] ) ) < min_dist ) {
			min_dist = d;
			ver1 = version( ans[0], ans[1], temp[min_p1.id-1].x, temp[min_p1.id-1].y );
			ver2 = version( ans[2], ans[3], temp[min_p2.id-1].x, temp[min_p2.id-1].y );
//			cout << ans[0] << " " << ans[1] << " " << ans[2] << " " << ans[3] << endl;
//			cout << temp[min_p1.id-1].x << " " << temp[min_p1.id-1].y << endl;
//			cout << temp[min_p2.id-1].x << " " << temp[min_p2.id-1].y << endl;
		}
	}

//	cout << min_dist << endl;
	printf( "%d %d %d %d\n", min_p1.id, ver1, min_p2.id, ver2 );

	free( px );
	free( py );
	free( temp );

	return 0;
}


/*******************************************************************************************************************************************
* File Name   : j.cpp
* Development : Wed 19 Oct 2011 09:40:46 PM IST
* Author      : Xeronix
*******************************************************************************************************************************************/

#include <iostream>
#include <cstdio>
#include <vector>
#include <math.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <string.h>
#include <cstdlib>
#include <sstream>
#include <stack>
#include <queue>
#include <numeric>
#include <utility>
#include <cctype>
#include <list>
#include <limits.h>
#include <signal.h>
#include <time.h>
#include <map>
#include <set>
#include <float.h>

#define TR(c, i) for ( typeof((c).begin()) i = (c).begin(); i != (c).end(); i++ )
#define FOR(i, a, b) for ( i = a; i <= b; i++ )
#define ROF(i, a, b) for ( i = a; i >= b; i-- )
#define ALL(v) (v).begin(), (v).end()
#define SORT(v) sort( ALL(v) )
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#define ABS(a) ((a) < (0) ? (a)*(-1) : (a))
#define SWAP(a, b) typeof(a) T; T=a; a=b; b=T;
#define SET(x,a) memset(x,a,sizeof(x))

//#define LIM
#ifdef LIM
	int S, D, Y;
	char *inp, *out, *ipos, *opos, DIG[30];
	#define FRMI inp=( char * )malloc( LIM*sizeof( char ) );fread_unlocked( inp,1,LIM,stdin );ipos=inp;
	#define FWM out=( char * )malloc( LIM*sizeof( char ) );opos=out;
	#define FWO fwrite_unlocked( out,opos-out,1,stdout );
        #define GETI(n) n=0;while(*ipos<33){ipos++;}if(*ipos=='-'){S=-1;ipos++;}else{S=1;}while(*ipos>='0'){n=10*n+(*ipos-'0');ipos++;}n*=S;
	#define PUTI(n) D=0;if(n<0){*opos++='-';n*=-1;}if(!n)*opos++='0';else{while(n){Y=n/10;DIG[D++]=n-Y*10+'0';n=Y;}\
	while(D--)*opos++=DIG[D];}
	#define PUTC(c) *opos++=c;
#endif

#define SQ(x) (x)*(x)
#define DIST( a,b ) ( SQ(a.x-b.x) + SQ(a.y-b.y) )
#define DISTI( a,b,c,d ) ( SQ(a+c) + SQ(b+d) )

using namespace std;
using namespace __gnu_cxx;

struct point {
	int x, y;
	int id;
};

bool comparex( point p, point q )
{
	return p.x < q.x;
}

bool comparey( point p, point q )
{
	return p.y < q.y;
}

point min_p1, min_p2;
int min_dist = INT_MAX;

void closest_pair( point *px, point *py, int n )
{
	int i, j;
	int d;

	if( n <= 3 ) {
		if( n >= 2 ) {
			FOR( i,0,n-2 ) {
				FOR( j,i+1,n-1 ) {
					if( px[i].id != px[j].id && ( d = DIST( px[i], px[j] ) ) < min_dist ) {
						min_dist = d;
						min_p1 = px[i];
						min_p2 = px[j];
					}
				}
			}
		}
	} else {
		int mid, divider;

		mid = n >> 1;

	//	point pxl[mid+1], pxr[mid+1];
	//	point pyl[mid+1], pyr[mid+1];
		point *pxl, *pxr;
		point *pyl, *pyr;
		pxl = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pxr = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pyl = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pyr = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );

		int pyl_len, pyr_len;

		FOR( i,0,mid ) {
			pxl[i] = px[i];
			if( mid+i+1 < n ) {
				pxr[i] = px[mid+i+1];
			}
		}

		divider = px[mid].x;
		pyl_len = pyr_len = 0;

		FOR( i,0,n-1 ) {
			if( py[i].x <= divider ) {
				pyl[pyl_len++] = py[i];
			} else {
				pyr[pyr_len++] = py[i];
			}
		}

		closest_pair( pxl, pyl, mid );
		closest_pair( pxr, pyr, n-mid-1 );

		point *pyd;
		pyd = ( struct point * )malloc( n*sizeof( struct point ) );
		int pyd_len = 0;

		FOR( i,0,n-1 ) {
			if( ABS( py[i].x-divider ) <= sqrt( min_dist ) ) {
				pyd[pyd_len++] = py[i];
			}
		}

		if( pyd_len > 1 ) {
			FOR( i,0,pyd_len-1 ) {
				for( j=i+1; j <= i+7 && j < pyd_len; j++ ) {
					if( pyd[i].id != pyd[j].id && ( d = DIST( pyd[i], pyd[j] ) ) <= min_dist ) {
						min_dist = d;
						min_p1 = pyd[i];
						min_p2 = pyd[j];
					}
				}
			}
		}

		free( pyd );
	}
}

inline int version( int a, int b, int x, int y )
{
	if( a == x && b == y ) {
		return 1;
	} else if( a == -x && b == y ) {
		return 2;
	} else if( a == x && b == -y ) {
		return 3;
	} else {
		return 4;
	}
}

int main()
{
	int i, j;
	int n, m, a, b;
	point pt;

	freopen( "input.txt", "r", stdin );
	freopen( "output.txt", "w", stdout );

	scanf( "%d", &n );

//	m = n << 2;
//	point px[n], py[n],  temp[n];;

	point *px, *py, *temp;

	px = ( struct point * )malloc( n*sizeof( struct point ) );
	py = ( struct point * )malloc( n*sizeof( struct point ) );
	temp = ( struct point * )malloc( n*sizeof( struct point ) );

	j = 0;

	FOR( i,0,n-1 ) {
		scanf( "%d%d", &a, &b );
		temp[i].x = a;
		temp[i].y = b;
		temp[i].id = i+1;
		pt.x = ABS(a);
		pt.y = ABS(b);
		pt.id = i+1;
		//	a = ABS(a); b = ABS(b);
	/*	pt.id = i+1;
		pt.x = a; pt.y = b; pt.v = 1; px[j] = py[j] = pt; j++;
		pt.x = a*-1; pt.y = b; pt.v = 2; px[j] = py[j] = pt; j++;
		pt.x = a; pt.y = b*-1; pt.v = 3; px[j] = py[j] = pt; j++;
		pt.x = a*-1; pt.y = b*-1; pt.v = 4; px[j] = py[j] = pt; j++;
		*/
//		pt.v = version( a, b, pt.x, pt.y );
		px[j] = py[j] = pt;
		j++;
	}

	sort( px, px+j, comparex );
	sort( py, py+j, comparey );

	closest_pair( px, py, n );

	int ans[4];

	ans[0] = min_p1.x;
	ans[1] = min_p1.y;
	ans[2] = min_p2.x;
	ans[3] = min_p2.y;

	int d, ver1, ver2;

	ver1 = 1;
	ver2 = 1;

	min_dist = DISTI( min_p1.x, min_p1.y, min_p2.x, min_p2.y );

	FOR( i,0,15 ) {
		FOR( j,0,3 ) {
			if ( i & (1<<j) ) {
				ans[j] = ABS(ans[j])*-1;
			}
		}

		if( ( d = DISTI( ans[0], ans[1], ans[2], ans[3] ) ) < min_dist ) {
			min_dist = d;
			ver1 = version( ans[0], ans[1], temp[min_p1.id-1].x, temp[min_p1.id-1].y );
			ver2 = version( ans[2], ans[3], temp[min_p2.id-1].x, temp[min_p2.id-1].y );
//			cout << ans[0] << " " << ans[1] << " " << ans[2] << " " << ans[3] << endl;
//			cout << temp[min_p1.id-1].x << " " << temp[min_p1.id-1].y << endl;
//			cout << temp[min_p2.id-1].x << " " << temp[min_p2.id-1].y << endl;
		}
	}

//	cout << min_dist << endl;
	printf( "%d %d %d %d\n", min_p1.id, ver1, min_p2.id, ver2 );

	free( px );
	free( py );
	free( temp );

	return 0;
}


/*******************************************************************************************************************************************
* File Name   : j.cpp
* Development : Wed 19 Oct 2011 09:40:46 PM IST
* Author      : Xeronix
*******************************************************************************************************************************************/

#include <iostream>
#include <cstdio>
#include <vector>
#include <math.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <string.h>
#include <cstdlib>
#include <sstream>
#include <stack>
#include <queue>
#include <numeric>
#include <utility>
#include <cctype>
#include <list>
#include <limits.h>
#include <signal.h>
#include <time.h>
#include <map>
#include <set>
#include <float.h>

#define TR(c, i) for ( typeof((c).begin()) i = (c).begin(); i != (c).end(); i++ )
#define FOR(i, a, b) for ( i = a; i <= b; i++ )
#define ROF(i, a, b) for ( i = a; i >= b; i-- )
#define ALL(v) (v).begin(), (v).end()
#define SORT(v) sort( ALL(v) )
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#define ABS(a) ((a) < (0) ? (a)*(-1) : (a))
#define SWAP(a, b) typeof(a) T; T=a; a=b; b=T;
#define SET(x,a) memset(x,a,sizeof(x))

//#define LIM
#ifdef LIM
	int S, D, Y;
	char *inp, *out, *ipos, *opos, DIG[30];
	#define FRMI inp=( char * )malloc( LIM*sizeof( char ) );fread_unlocked( inp,1,LIM,stdin );ipos=inp;
	#define FWM out=( char * )malloc( LIM*sizeof( char ) );opos=out;
	#define FWO fwrite_unlocked( out,opos-out,1,stdout );
        #define GETI(n) n=0;while(*ipos<33){ipos++;}if(*ipos=='-'){S=-1;ipos++;}else{S=1;}while(*ipos>='0'){n=10*n+(*ipos-'0');ipos++;}n*=S;
	#define PUTI(n) D=0;if(n<0){*opos++='-';n*=-1;}if(!n)*opos++='0';else{while(n){Y=n/10;DIG[D++]=n-Y*10+'0';n=Y;}\
	while(D--)*opos++=DIG[D];}
	#define PUTC(c) *opos++=c;
#endif

#define SQ(x) (x)*(x)
#define DIST( a,b ) ( SQ(a.x-b.x) + SQ(a.y-b.y) )

using namespace std;
using namespace __gnu_cxx;

struct point {
	int x, y;
	int v;
	int id;
};

bool comparex( point p, point q )
{
	return p.x < q.x;
}

bool comparey( point p, point q )
{
	return p.y < q.y;
}

point min_p1, min_p2;
int min_dist = INT_MAX;

void closest_pair( point *px, point *py, int n )
{
	int i, j;
	int d;

	if( n <= 3 ) {
		if( n >= 2 ) {
			FOR( i,0,n-2 ) {
				FOR( j,i+1,n-1 ) {
					if( px[i].id != px[j].id && ( d = DIST( px[i], px[j] ) ) < min_dist ) {
						min_dist = d;
						min_p1 = px[i];
						min_p2 = px[j];
					}
				}
			}
		}
	} else {
		int mid, divider;

		mid = n >> 1;

		point pxl[mid+1], pxr[mid+1];
		point pyl[mid+1], pyr[mid+1];

		int pyl_len, pyr_len;

		FOR( i,0,mid ) {
			pxl[i] = px[i];
			if( mid+i+1 < n ) {
				pxr[i] = px[mid+i+1];
			}
		}

		divider = px[mid].x;
		pyl_len = pyr_len = 0;

		FOR( i,0,n-1 ) {
			if( py[i].x <= divider ) {
				pyl[pyl_len++] = py[i];
			} else {
				pyr[pyr_len++] = py[i];
			}
		}

		closest_pair( pxl, pyl, mid );
		closest_pair( pxr, pyr, n-mid-1 );

		point pyd[n];
		int pyd_len = 0;

		FOR( i,0,n-1 ) {
			if( ABS( py[i].x-divider ) <= sqrt( min_dist ) ) {
				pyd[pyd_len++] = py[i];
			}
		}

		if( pyd_len > 1 ) {
			FOR( i,0,pyd_len-1 ) {
				for( j=i+1; j <= i+7 && j < pyd_len; j++ ) {
					if( pyd[i].id != pyd[j].id && ( d = DIST( pyd[i], pyd[j] ) ) <= min_dist ) {
						min_dist = d;
						min_p1 = pyd[i];
						min_p2 = pyd[j];
					}
				}
			}
		}
	}
}

inline int version( int a, int b, int x, int y )
{
	if( a == x && b == y ) {
		return 1;
	} else if( a == -x && b == y ) {
		return 2;
	} else if( a == x && b == -y ) {
		return 3;
	} else {
		return 4;
	}
}

int main()
{
	int i, j;
	int n, a, b;
	point pt;

	freopen( "input.txt", "r", stdin );
	freopen( "output.txt", "w", stdout );

	scanf( "%d", &n );

	point px[n], py[n];

	j = 0;

	FOR( i,0,n-1 ) {
		scanf( "%d%d", &a, &b );
		pt.x = ABS(a);
		pt.y = ABS(b);
		pt.id = i+1;
		pt.v = version( a, b, pt.x, pt.y );
		px[j] = py[j] = pt;
		j++;
	}

	sort( px, px+j, comparex );
	sort( py, py+j, comparey );

	closest_pair( px, py, n );

	printf( "%d %d %d %d\n", min_p1.id, min_p1.v, min_p2.id, min_p2.v );

	return 0;
}


/*******************************************************************************************************************************************
* File Name   : j.cpp
* Development : Wed 19 Oct 2011 09:40:46 PM IST
* Author      : Xeronix
*******************************************************************************************************************************************/

#include <iostream>
#include <cstdio>
#include <vector>
#include <math.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <string.h>
#include <cstdlib>
#include <sstream>
#include <stack>
#include <queue>
#include <numeric>
#include <utility>
#include <cctype>
#include <list>
#include <limits.h>
#include <signal.h>
#include <time.h>
#include <map>
#include <set>
#include <float.h>

#define TR(c, i) for ( typeof((c).begin()) i = (c).begin(); i != (c).end(); i++ )
#define FOR(i, a, b) for ( i = a; i <= b; i++ )
#define ROF(i, a, b) for ( i = a; i >= b; i-- )
#define ALL(v) (v).begin(), (v).end()
#define SORT(v) sort( ALL(v) )
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#define ABS(a) ((a) < (0) ? (a)*(-1) : (a))
#define SWAP(a, b) typeof(a) T; T=a; a=b; b=T;
#define SET(x,a) memset(x,a,sizeof(x))

//#define LIM
#ifdef LIM
	int S, D, Y;
	char *inp, *out, *ipos, *opos, DIG[30];
	#define FRMI inp=( char * )malloc( LIM*sizeof( char ) );fread_unlocked( inp,1,LIM,stdin );ipos=inp;
	#define FWM out=( char * )malloc( LIM*sizeof( char ) );opos=out;
	#define FWO fwrite_unlocked( out,opos-out,1,stdout );
        #define GETI(n) n=0;while(*ipos<33){ipos++;}if(*ipos=='-'){S=-1;ipos++;}else{S=1;}while(*ipos>='0'){n=10*n+(*ipos-'0');ipos++;}n*=S;
	#define PUTI(n) D=0;if(n<0){*opos++='-';n*=-1;}if(!n)*opos++='0';else{while(n){Y=n/10;DIG[D++]=n-Y*10+'0';n=Y;}\
	while(D--)*opos++=DIG[D];}
	#define PUTC(c) *opos++=c;
#endif

#define SQ(x) (x)*(x)
#define DIST( a,b ) ( SQ(a.x-b.x) + SQ(a.y-b.y) )
#define DISTI( a,b,c,d ) ( SQ(a+c) + SQ(b+d) )

using namespace std;
using namespace __gnu_cxx;

struct point {
	int x, y;
	int id;
};

bool comparex( point p, point q )
{
	return p.x < q.x;
}

bool comparey( point p, point q )
{
	return p.y < q.y;
}

point min_p1, min_p2;
int min_dist = INT_MAX;

void closest_pair( point *px,  point *py, int n )
{
	int i, j;
	int d;

	if( n <= 10 ) {
		if( n >= 2 ) {
			FOR( i,0,n-2 ) {
				FOR( j,i+1,n-1 ) {
					if( ( d = DIST( px[i], px[j] ) ) < min_dist ) {
						min_dist = d;
						min_p1 = px[i];
						min_p2 = px[j];
					}
				}
			}
		}
	} else {
		int mid, divider;

		mid = n >> 1;

//		point pyl[mid+1], pyr[mid+1];
		point *pyl, *pyr;
		pyl = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pyr = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );

		int pyl_len, pyr_len;

		divider = px[mid].x;
		pyl_len = pyr_len = 0;

		FOR( i,0,n-1 ) {
			if( py[i].x <= divider ) {
				pyl[pyl_len++] = py[i];
			} else {
				pyr[pyr_len++] = py[i];
			}
		}

		closest_pair( px, pyl, mid+1 );
		closest_pair( px+mid+1, pyr, n-mid-1 );

		point *pyd;
		pyd = ( struct point * )malloc( n*sizeof( struct point ) );
		int pyd_len = 0;

		FOR( i,0,n-1 ) {
			if( ABS( py[i].x-divider ) <= sqrt( min_dist ) ) {
				pyd[pyd_len++] = py[i];
			}
		}

		if( pyd_len > 1 ) {
			FOR( i,0,pyd_len-1 ) {
				for( j=i+1; j <= i+7 && j < pyd_len; j++ ) {
					if( ( d = DIST( pyd[i], pyd[j] ) ) < min_dist ) {
						min_dist = d;
						min_p1 = pyd[i];
						min_p2 = pyd[j];
					}
				}
			}
		}

		free( pyd );
		free( pyl );
		free( pyr );
	}
}

inline int version( int a, int b, int x, int y )
{
	if( a == x && b == y ) {
		return 1;
	} else if( a == -x && b == y ) {
		return 2;
	} else if( a == x && b == -y ) {
		return 3;
	} else {
		return 4;
	}
}

int main()
{
	int i, j;
	int n, m, a, b;
	point pt;

	freopen( "input.txt", "r", stdin );
	freopen( "output.txt", "w", stdout );

	scanf( "%d", &n );

	point *px, *py;
	int *ver;

//	point px[n], py[n];
//	int ver[n];
	px = ( struct point * )malloc( n*sizeof( struct point ) );
	py = ( struct point * )malloc( n*sizeof( struct point ) );
	ver = ( int * )malloc( n*sizeof( int ) );

	j = 0;

	FOR( i,0,n-1 ) {
		scanf( "%d%d", &a, &b );
		pt.x = ABS(a);
		pt.y = ABS(b);
		pt.id = i+1;
		ver[i] = version( a, b, pt.x, pt.y );
		px[j] = py[j] = pt;
		j++;
	}

	sort( px, px+j, comparex );
	sort( py, py+j, comparey );

	closest_pair( px, py, n );

	printf( "%d %d %d %d\n", min_p1.id, ver[min_p1.id-1], min_p2.id, 5-ver[min_p2.id-1] );

	free( px );
	free( py );
	free( ver );

	return 0;
}


/*******************************************************************************************************************************************
* File Name   : j.cpp
* Development : Wed 19 Oct 2011 09:40:46 PM IST
* Author      : Xeronix
*******************************************************************************************************************************************/

#include <iostream>
#include <cstdio>
#include <vector>
#include <math.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <string.h>
#include <cstdlib>
#include <sstream>
#include <stack>
#include <queue>
#include <numeric>
#include <utility>
#include <cctype>
#include <list>
#include <limits.h>
#include <signal.h>
#include <time.h>
#include <map>
#include <set>
#include <float.h>

#define TR(c, i) for ( typeof((c).begin()) i = (c).begin(); i != (c).end(); i++ )
#define FOR(i, a, b) for ( i = a; i <= b; i++ )
#define ROF(i, a, b) for ( i = a; i >= b; i-- )
#define ALL(v) (v).begin(), (v).end()
#define SORT(v) sort( ALL(v) )
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#define ABS(a) ((a) < (0) ? (a)*(-1) : (a))
#define SWAP(a, b) typeof(a) T; T=a; a=b; b=T;
#define SET(x,a) memset(x,a,sizeof(x))

//#define LIM
#ifdef LIM
	int S, D, Y;
	char *inp, *out, *ipos, *opos, DIG[30];
	#define FRMI inp=( char * )malloc( LIM*sizeof( char ) );fread_unlocked( inp,1,LIM,stdin );ipos=inp;
	#define FWM out=( char * )malloc( LIM*sizeof( char ) );opos=out;
	#define FWO fwrite_unlocked( out,opos-out,1,stdout );
        #define GETI(n) n=0;while(*ipos<33){ipos++;}if(*ipos=='-'){S=-1;ipos++;}else{S=1;}while(*ipos>='0'){n=10*n+(*ipos-'0');ipos++;}n*=S;
	#define PUTI(n) D=0;if(n<0){*opos++='-';n*=-1;}if(!n)*opos++='0';else{while(n){Y=n/10;DIG[D++]=n-Y*10+'0';n=Y;}\
	while(D--)*opos++=DIG[D];}
	#define PUTC(c) *opos++=c;
#endif

#define SQ(x) (x)*(x)
#define DIST( a,b ) ( SQ(a.x-b.x) + SQ(a.y-b.y) )
#define DISTI( a,b,c,d ) ( SQ(a+c) + SQ(b+d) )

using namespace std;
using namespace __gnu_cxx;

struct point {
	int x, y;
	int v;
	int id;
};

bool comparex( point p, point q )
{
	return p.x < q.x;
}

bool comparey( point p, point q )
{
	return p.y < q.y;
}

point min_p1, min_p2;
int min_dist = INT_MAX;

void closest_pair( point *px, point *py, int n )
{
	int i, j;
	int d;

	if( n <= 3 ) {
		if( n >= 2 ) {
			FOR( i,0,n-2 ) {
				FOR( j,i+1,n-1 ) {
					if( px[i].id != px[j].id && ( d = DIST( px[i], px[j] ) ) < min_dist ) {
						min_dist = d;
						min_p1 = px[i];
						min_p2 = px[j];
					}
				}
			}
		}
	} else {
		int mid, divider;

		mid = n >> 1;

		point pxl[mid+1], pxr[mid+1];
		point pyl[mid+1], pyr[mid+1];

		int pyl_len, pyr_len;

		FOR( i,0,mid ) {
			pxl[i] = px[i];
			if( mid+i+1 < n ) {
				pxr[i] = px[mid+i+1];
			}
		}

		divider = px[mid].x;
		pyl_len = pyr_len = 0;

		FOR( i,0,n-1 ) {
			if( py[i].x <= divider ) {
				pyl[pyl_len++] = py[i];
			} else {
				pyr[pyr_len++] = py[i];
			}
		}

		closest_pair( pxl, pyl, mid );
		closest_pair( pxr, pyr, n-mid-1 );

		point pyd[n];
		int pyd_len = 0;

		FOR( i,0,n-1 ) {
			if( ABS( py[i].x-divider ) <= sqrt( min_dist ) ) {
				pyd[pyd_len++] = py[i];
			}
		}

		if( pyd_len > 1 ) {
			FOR( i,0,pyd_len-1 ) {
				for( j=i+1; j <= i+7 && j < pyd_len; j++ ) {
					if( pyd[i].id != pyd[j].id && ( d = DIST( pyd[i], pyd[j] ) ) <= min_dist ) {
						min_dist = d;
						min_p1 = pyd[i];
						min_p2 = pyd[j];
					}
				}
			}
		}
	}
}

inline int version( int a, int b, int x, int y )
{
	if( a == x && b == y ) {
		return 1;
	} else if( a == -x && b == y ) {
		return 2;
	} else if( a == x && b == -y ) {
		return 3;
	} else {
		return 4;
	}
}

int main()
{
	int i, j;
	int n, m, a, b;
	point pt;

	freopen( "input.txt", "r", stdin );
	freopen( "output.txt", "w", stdout );

	scanf( "%d", &n );

//	m = n << 2;
	point px[n], py[n],  temp[n];;

	j = 0;

	FOR( i,0,n-1 ) {
		scanf( "%d%d", &a, &b );
		temp[i].x = a;
		temp[i].y = b;
		temp[i].id = i+1;
		pt.x = ABS(a);
		pt.y = ABS(b);
		pt.id = i+1;
		//	a = ABS(a); b = ABS(b);
	/*	pt.id = i+1;
		pt.x = a; pt.y = b; pt.v = 1; px[j] = py[j] = pt; j++;
		pt.x = a*-1; pt.y = b; pt.v = 2; px[j] = py[j] = pt; j++;
		pt.x = a; pt.y = b*-1; pt.v = 3; px[j] = py[j] = pt; j++;
		pt.x = a*-1; pt.y = b*-1; pt.v = 4; px[j] = py[j] = pt; j++;
		*/
//		pt.v = version( a, b, pt.x, pt.y );
		px[j] = py[j] = pt;
		j++;
	}

	sort( px, px+j, comparex );
	sort( py, py+j, comparey );

	closest_pair( px, py, n );

	int ans[4];

	ans[0] = min_p1.x;
	ans[1] = min_p1.y;
	ans[2] = min_p2.x;
	ans[3] = min_p2.y;

	int d, ver1, ver2;

	ver1 = 1;
	ver2 = 1;

	min_dist = DISTI( min_p1.x, min_p1.y, min_p2.x, min_p2.y );

	FOR( i,0,15 ) {
		FOR( j,0,3 ) {
			if ( i & (1<<j) ) {
				ans[j] = ABS(ans[j])*-1;
			}
		}

		if( ( d = DISTI( ans[0], ans[1], ans[2], ans[3] ) ) < min_dist ) {
			min_dist = d;
			ver1 = version( ans[0], ans[1], temp[min_p1.id-1].x, temp[min_p1.id-1].y );
			ver2 = version( ans[2], ans[3], temp[min_p2.id-1].x, temp[min_p2.id-1].y );
//			cout << ans[0] << " " << ans[1] << " " << ans[2] << " " << ans[3] << endl;
//			cout << temp[min_p1.id-1].x << " " << temp[min_p1.id-1].y << endl;
//			cout << temp[min_p2.id-1].x << " " << temp[min_p2.id-1].y << endl;
		}
	}

//	cout << min_dist << endl;
	printf( "%d %d %d %d\n", min_p1.id, ver1, min_p2.id, ver2 );

	return 0;
}


/*******************************************************************************************************************************************
* File Name   : j.cpp
* Development : Wed 19 Oct 2011 09:40:46 PM IST
* Author      : Xeronix
*******************************************************************************************************************************************/

#include <iostream>
#include <cstdio>
#include <vector>
#include <math.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <string.h>
#include <cstdlib>
#include <sstream>
#include <stack>
#include <queue>
#include <numeric>
#include <utility>
#include <cctype>
#include <list>
#include <limits.h>
#include <signal.h>
#include <time.h>
#include <map>
#include <set>
#include <float.h>

#define TR(c, i) for ( typeof((c).begin()) i = (c).begin(); i != (c).end(); i++ )
#define FOR(i, a, b) for ( i = a; i <= b; i++ )
#define ROF(i, a, b) for ( i = a; i >= b; i-- )
#define ALL(v) (v).begin(), (v).end()
#define SORT(v) sort( ALL(v) )
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#define ABS(a) ((a) < (0) ? (a)*(-1) : (a))
#define SWAP(a, b) typeof(a) T; T=a; a=b; b=T;
#define SET(x,a) memset(x,a,sizeof(x))

//#define LIM
#ifdef LIM
	int S, D, Y;
	char *inp, *out, *ipos, *opos, DIG[30];
	#define FRMI inp=( char * )malloc( LIM*sizeof( char ) );fread_unlocked( inp,1,LIM,stdin );ipos=inp;
	#define FWM out=( char * )malloc( LIM*sizeof( char ) );opos=out;
	#define FWO fwrite_unlocked( out,opos-out,1,stdout );
        #define GETI(n) n=0;while(*ipos<33){ipos++;}if(*ipos=='-'){S=-1;ipos++;}else{S=1;}while(*ipos>='0'){n=10*n+(*ipos-'0');ipos++;}n*=S;
	#define PUTI(n) D=0;if(n<0){*opos++='-';n*=-1;}if(!n)*opos++='0';else{while(n){Y=n/10;DIG[D++]=n-Y*10+'0';n=Y;}\
	while(D--)*opos++=DIG[D];}
	#define PUTC(c) *opos++=c;
#endif

#define SQ(x) (x)*(x)
#define DIST( a,b ) ( SQ(a.x-b.x) + SQ(a.y-b.y) )
#define DISTI( a,b,c,d ) ( SQ(a+c) + SQ(b+d) )

using namespace std;
using namespace __gnu_cxx;

struct point {
	int x, y;
	int id;
};

bool comparex( point p, point q )
{
	return p.x < q.x;
}

bool comparey( point p, point q )
{
	return p.y < q.y;
}

point min_p1, min_p2;
int min_dist = INT_MAX;

void closest_pair( point *px, point *py, int n )
{
	int i, j;
	int d;

	if( n <= 3 ) {
		if( n >= 2 ) {
			FOR( i,0,n-2 ) {
				FOR( j,i+1,n-1 ) {
					if( ( d = DIST( px[i], px[j] ) ) < min_dist ) {
						min_dist = d;
						min_p1 = px[i];
						min_p2 = px[j];
					}
				}
			}
		}
	} else {
		int mid, divider;

		mid = n >> 1;

//		point pxl[mid+1], pxr[mid+1];
//		point pyl[mid+1], pyr[mid+1];
		point *pxl, *pxr;
		point *pyl, *pyr;
		pxl = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pxr = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pyl = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pyr = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );

		int pyl_len, pyr_len;

		FOR( i,0,mid ) {
			pxl[i] = px[i];
			if( mid+i+1 < n ) {
				pxr[i] = px[mid+i+1];
			}
		}

		divider = px[mid].x;
		pyl_len = pyr_len = 0;

		FOR( i,0,n-1 ) {
			if( py[i].x <= divider ) {
				pyl[pyl_len++] = py[i];
			} else {
				pyr[pyr_len++] = py[i];
			}
		}

		closest_pair( pxl, pyl, mid );
		closest_pair( pxr, pyr, n-mid-1 );

//		point pyd[100];
		point *pyd;
		pyd = ( struct point * )malloc( n*sizeof( struct point ) );
		int pyd_len = 0;

		FOR( i,0,n-1 ) {
			if( ABS( py[i].x-divider ) <= sqrt( min_dist ) ) {
				pyd[pyd_len++] = py[i];
			}
		}

		if( pyd_len > 1 ) {
			FOR( i,0,pyd_len-1 ) {
				for( j=i+1; j <= i+7 && j < pyd_len; j++ ) {
					if( ( d = DIST( pyd[i], pyd[j] ) ) < min_dist ) {
						min_dist = d;
						min_p1 = pyd[i];
						min_p2 = pyd[j];
					}
				}
			}
		}

		free( pyd );
		free(pxl);
		free(pxr);
//		free(pyl);
//		free(pyr);
	}
}

inline int version( int a, int b, int x, int y )
{
	if( a == x && b == y ) {
		return 1;
	} else if( a == -x && b == y ) {
		return 2;
	} else if( a == x && b == -y ) {
		return 3;
	} else {
		return 4;
	}
}

int main()
{
	int i, j;
	int n, m, a, b;
	point pt;

	freopen( "input.txt", "r", stdin );
	freopen( "output.txt", "w", stdout );

	scanf( "%d", &n );

//	m = n << 2;
//	point px[n], py[n],  temp[n];;

//	point *px, *py, *temp;

	point px[n], py[n];
	int ver[n];
//	px = ( struct point * )malloc( n*sizeof( struct point ) );
//	py = ( struct point * )malloc( n*sizeof( struct point ) );

	j = 0;

	FOR( i,0,n-1 ) {
		scanf( "%d%d", &a, &b );
		pt.x = ABS(a);
		pt.y = ABS(b);
		pt.id = i+1;
		ver[i] = version( a, b, pt.x, pt.y );
		px[j] = py[j] = pt;
		j++;
	}

	sort( px, px+j, comparex );
	sort( py, py+j, comparey );

	closest_pair( px, py, n );

//	cout << min_dist << endl;
	printf( "%d %d %d %d\n", min_p1.id, ver[min_p1.id-1], min_p2.id, 5-ver[min_p2.id-1] );

//	free( px );
//	free( py );

	return 0;
}


/*******************************************************************************************************************************************
* File Name   : j.cpp
* Development : Wed 19 Oct 2011 09:40:46 PM IST
* Author      : Xeronix
*******************************************************************************************************************************************/

#include <iostream>
#include <cstdio>
#include <vector>
#include <math.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <string.h>
#include <cstdlib>
#include <sstream>
#include <stack>
#include <queue>
#include <numeric>
#include <utility>
#include <cctype>
#include <list>
#include <limits.h>
#include <signal.h>
#include <time.h>
#include <map>
#include <set>
#include <float.h>

#define TR(c, i) for ( typeof((c).begin()) i = (c).begin(); i != (c).end(); i++ )
#define FOR(i, a, b) for ( i = a; i <= b; i++ )
#define ROF(i, a, b) for ( i = a; i >= b; i-- )
#define ALL(v) (v).begin(), (v).end()
#define SORT(v) sort( ALL(v) )
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#define ABS(a) ((a) < (0) ? (a)*(-1) : (a))
#define SWAP(a, b) typeof(a) T; T=a; a=b; b=T;
#define SET(x,a) memset(x,a,sizeof(x))

//#define LIM
#ifdef LIM
	int S, D, Y;
	char *inp, *out, *ipos, *opos, DIG[30];
	#define FRMI inp=( char * )malloc( LIM*sizeof( char ) );fread_unlocked( inp,1,LIM,stdin );ipos=inp;
	#define FWM out=( char * )malloc( LIM*sizeof( char ) );opos=out;
	#define FWO fwrite_unlocked( out,opos-out,1,stdout );
        #define GETI(n) n=0;while(*ipos<33){ipos++;}if(*ipos=='-'){S=-1;ipos++;}else{S=1;}while(*ipos>='0'){n=10*n+(*ipos-'0');ipos++;}n*=S;
	#define PUTI(n) D=0;if(n<0){*opos++='-';n*=-1;}if(!n)*opos++='0';else{while(n){Y=n/10;DIG[D++]=n-Y*10+'0';n=Y;}\
	while(D--)*opos++=DIG[D];}
	#define PUTC(c) *opos++=c;
#endif

#define SQ(x) (x)*(x)
#define DIST( a,b ) ( SQ(a.x-b.x) + SQ(a.y-b.y) )

using namespace std;
using namespace __gnu_cxx;

struct point {
	int x, y;
	int v;
	int id;
};

bool comparex( point p, point q )
{
	return p.x < q.x;
}

bool comparey( point p, point q )
{
	return p.y < q.y;
}

point min_p1, min_p2;
int min_dist = INT_MAX;

void closest_pair( point *px, point *py, int n )
{
	int i, j;
	int d;

	if( n <= 3 ) {
		if( n >= 2 ) {
			FOR( i,0,n-2 ) {
				FOR( j,i+1,n-1 ) {
					if( px[i].id != px[j].id && ( d = DIST( px[i], px[j] ) ) < min_dist ) {
						min_dist = d;
						min_p1 = px[i];
						min_p2 = px[j];
					}
				}
			}
		}
	} else {
		int mid, divider;

		mid = n >> 1;

		point pxl[mid+1], pxr[mid+1];
		point pyl[mid+1], pyr[mid+1];

		int pyl_len, pyr_len;

		FOR( i,0,mid ) {
			pxl[i] = px[i];
			if( mid+i+1 < n ) {
				pxr[i] = px[mid+i+1];
			}
		}

		divider = px[mid].x;
		pyl_len = pyr_len = 0;

		FOR( i,0,n-1 ) {
			if( py[i].x <= divider ) {
				pyl[pyl_len++] = py[i];
			} else {
				pyr[pyr_len++] = py[i];
			}
		}

		closest_pair( pxl, pyl, mid );
		closest_pair( pxr, pyr, n-mid-1 );

		point pyd[n];
		int pyd_len = 0;

		FOR( i,0,n-1 ) {
			if( ABS( py[i].x-divider ) <= sqrt( min_dist ) ) {
				pyd[pyd_len++] = py[i];
			}
		}

		if( pyd_len > 1 ) {
			FOR( i,0,pyd_len-1 ) {
				for( j=i+1; j <= i+7 && j < pyd_len; j++ ) {
					if( pyd[i].id != pyd[j].id && ( d = DIST( pyd[i], pyd[j] ) ) <= min_dist ) {
						min_dist = d;
						min_p1 = pyd[i];
						min_p2 = pyd[j];
					}
				}
			}
		}
	}
}

int main()
{
	int i, j;
	int n, m, a, b;
	point pt;

	freopen( "input.txt", "r", stdin );
	freopen( "output.txt", "w", stdout );

	scanf( "%d", &n );

	m = n << 2;
	point px[m], py[m];

	j = 0;

	FOR( i,0,n-1 ) {
		scanf( "%d%d", &a, &b );
		a = ABS(a);
		b = ABS(b);
		pt.id = i+1;
		pt.x = a; pt.y = b; pt.v = 1; px[j] = py[j] = pt; j++;
		pt.x *= -1; pt.v = 2; px[j] = py[j] = pt; j++;
		pt.y *= -1; pt.v = 4; px[j] = py[j] = pt; j++;
		pt.x *= -1; pt.v = 3; px[j] = py[j] = pt; j++;
	}

	sort( px, px+j, comparex );
	sort( py, py+j, comparey );

	closest_pair( px, py, m );

	printf( "%d %d %d %d\n", min_p1.id, min_p1.v, min_p2.id, min_p2.v );

	return 0;
}


/*******************************************************************************************************************************************
* File Name   : j.cpp
* Development : Wed 19 Oct 2011 09:40:46 PM IST
* Author      : Xeronix
*******************************************************************************************************************************************/

#include <iostream>
#include <cstdio>
#include <vector>
#include <math.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <string.h>
#include <cstdlib>
#include <sstream>
#include <stack>
#include <queue>
#include <numeric>
#include <utility>
#include <cctype>
#include <list>
#include <limits.h>
#include <signal.h>
#include <time.h>
#include <map>
#include <set>
#include <float.h>

#define TR(c, i) for ( typeof((c).begin()) i = (c).begin(); i != (c).end(); i++ )
#define FOR(i, a, b) for ( i = a; i <= b; i++ )
#define ROF(i, a, b) for ( i = a; i >= b; i-- )
#define ALL(v) (v).begin(), (v).end()
#define SORT(v) sort( ALL(v) )
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#define ABS(a) ((a) < (0) ? (a)*(-1) : (a))
#define SWAP(a, b) typeof(a) T; T=a; a=b; b=T;
#define SET(x,a) memset(x,a,sizeof(x))

//#define LIM
#ifdef LIM
	int S, D, Y;
	char *inp, *out, *ipos, *opos, DIG[30];
	#define FRMI inp=( char * )malloc( LIM*sizeof( char ) );fread_unlocked( inp,1,LIM,stdin );ipos=inp;
	#define FWM out=( char * )malloc( LIM*sizeof( char ) );opos=out;
	#define FWO fwrite_unlocked( out,opos-out,1,stdout );
        #define GETI(n) n=0;while(*ipos<33){ipos++;}if(*ipos=='-'){S=-1;ipos++;}else{S=1;}while(*ipos>='0'){n=10*n+(*ipos-'0');ipos++;}n*=S;
	#define PUTI(n) D=0;if(n<0){*opos++='-';n*=-1;}if(!n)*opos++='0';else{while(n){Y=n/10;DIG[D++]=n-Y*10+'0';n=Y;}\
	while(D--)*opos++=DIG[D];}
	#define PUTC(c) *opos++=c;
#endif

#define SQ(x) (x)*(x)
#define DIST( a,b ) ( SQ(a.x-b.x) + SQ(a.y-b.y) )
#define DISTI( a,b,c,d ) ( SQ(a+c) + SQ(b+d) )

using namespace std;
using namespace __gnu_cxx;

struct point {
	int x, y;
	int v;
	int id;
};

bool comparex( point p, point q )
{
	return p.x < q.x;
}

bool comparey( point p, point q )
{
	return p.y < q.y;
}

point min_p1, min_p2;
int min_dist = INT_MAX;

void closest_pair( point *px, point *py, int n )
{
	int i, j;
	int d;

	if( n <= 3 ) {
		if( n >= 2 ) {
			FOR( i,0,n-2 ) {
				FOR( j,i+1,n-1 ) {
					if( px[i].id != px[j].id && ( d = DIST( px[i], px[j] ) ) < min_dist ) {
						min_dist = d;
						min_p1 = px[i];
						min_p2 = px[j];
					}
				}
			}
		}
	} else {
		int mid, divider;

		mid = n >> 1;

		point *pxl, *pxr;
		point *pyl, *pyr;
		pxl = ( point * )malloc( (mid+1)*sizeof( point ) );
		pxr = ( point * )malloc( (mid+1)*sizeof( point ) );
		pyl = ( point * )malloc( (mid+1)*sizeof( point ) );
		pyr = ( point * )malloc( (mid+1)*sizeof( point ) );

		int pyl_len, pyr_len;

		FOR( i,0,mid ) {
			pxl[i] = px[i];
			if( mid+i+1 < n ) {
				pxr[i] = px[mid+i+1];
			}
		}

		divider = px[mid].x;
		pyl_len = pyr_len = 0;

		FOR( i,0,n-1 ) {
			if( py[i].x <= divider ) {
				pyl[pyl_len++] = py[i];
			} else {
				pyr[pyr_len++] = py[i];
			}
		}

		closest_pair( pxl, pyl, mid );
		closest_pair( pxr, pyr, n-mid-1 );

		point *pyd;
		pyd = ( point * )malloc( n*sizeof( point ) );
		int pyd_len = 0;

		FOR( i,0,n-1 ) {
			if( ABS( py[i].x-divider ) <= sqrt( min_dist ) ) {
				pyd[pyd_len++] = py[i];
			}
		}

		if( pyd_len > 1 ) {
			FOR( i,0,pyd_len-1 ) {
				for( j=i+1; j <= i+7 && j < pyd_len; j++ ) {
					if( pyd[i].id != pyd[j].id && ( d = DIST( pyd[i], pyd[j] ) ) <= min_dist ) {
						min_dist = d;
						min_p1 = pyd[i];
						min_p2 = pyd[j];
					}
				}
			}
		}
	}
}

inline int version( int a, int b, int x, int y )
{
	if( a == x && b == y ) {
		return 1;
	} else if( a == -x && b == y ) {
		return 2;
	} else if( a == x && b == -y ) {
		return 3;
	} else {
		return 4;
	}
}

int main()
{
	int i, j;
	int n, m, a, b;
	point pt;

	freopen( "input.txt", "r", stdin );
	freopen( "output.txt", "w", stdout );

	scanf( "%d", &n );

//	m = n << 2;
//	point px[n], py[n],  temp[n];;

	point *px, *py, *temp;

	px = ( point * )malloc( n*sizeof( point ) );
	py = ( point * )malloc( n*sizeof( point ) );
	temp = ( point * )malloc( n*sizeof( point ) );

	j = 0;

	FOR( i,0,n-1 ) {
		scanf( "%d%d", &a, &b );
		temp[i].x = a;
		temp[i].y = b;
		temp[i].id = i+1;
		pt.x = ABS(a);
		pt.y = ABS(b);
		pt.id = i+1;
		//	a = ABS(a); b = ABS(b);
	/*	pt.id = i+1;
		pt.x = a; pt.y = b; pt.v = 1; px[j] = py[j] = pt; j++;
		pt.x = a*-1; pt.y = b; pt.v = 2; px[j] = py[j] = pt; j++;
		pt.x = a; pt.y = b*-1; pt.v = 3; px[j] = py[j] = pt; j++;
		pt.x = a*-1; pt.y = b*-1; pt.v = 4; px[j] = py[j] = pt; j++;
		*/
//		pt.v = version( a, b, pt.x, pt.y );
		px[j] = py[j] = pt;
		j++;
	}

	sort( px, px+j, comparex );
	sort( py, py+j, comparey );

	closest_pair( px, py, n );

	int ans[4];

	ans[0] = min_p1.x;
	ans[1] = min_p1.y;
	ans[2] = min_p2.x;
	ans[3] = min_p2.y;

	int d, ver1, ver2;

	ver1 = 1;
	ver2 = 1;

	min_dist = DISTI( min_p1.x, min_p1.y, min_p2.x, min_p2.y );

	FOR( i,0,15 ) {
		FOR( j,0,3 ) {
			if ( i & (1<<j) ) {
				ans[j] = ABS(ans[j])*-1;
			}
		}

		if( ( d = DISTI( ans[0], ans[1], ans[2], ans[3] ) ) < min_dist ) {
			min_dist = d;
			ver1 = version( ans[0], ans[1], temp[min_p1.id-1].x, temp[min_p1.id-1].y );
			ver2 = version( ans[2], ans[3], temp[min_p2.id-1].x, temp[min_p2.id-1].y );
//			cout << ans[0] << " " << ans[1] << " " << ans[2] << " " << ans[3] << endl;
//			cout << temp[min_p1.id-1].x << " " << temp[min_p1.id-1].y << endl;
//			cout << temp[min_p2.id-1].x << " " << temp[min_p2.id-1].y << endl;
		}
	}

//	cout << min_dist << endl;
	printf( "%d %d %d %d\n", min_p1.id, ver1, min_p2.id, ver2 );

	return 0;
}


/*******************************************************************************************************************************************
* File Name   : j.cpp
* Development : Wed 19 Oct 2011 09:40:46 PM IST
* Author      : Xeronix
*******************************************************************************************************************************************/

#include <iostream>
#include <cstdio>
#include <vector>
#include <math.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <string.h>
#include <cstdlib>
#include <sstream>
#include <stack>
#include <queue>
#include <numeric>
#include <utility>
#include <cctype>
#include <list>
#include <limits.h>
#include <signal.h>
#include <time.h>
#include <map>
#include <set>
#include <float.h>

#define TR(c, i) for ( typeof((c).begin()) i = (c).begin(); i != (c).end(); i++ )
#define FOR(i, a, b) for ( i = a; i <= b; i++ )
#define ROF(i, a, b) for ( i = a; i >= b; i-- )
#define ALL(v) (v).begin(), (v).end()
#define SORT(v) sort( ALL(v) )
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#define ABS(a) ((a) < (0) ? (a)*(-1) : (a))
#define SWAP(a, b) typeof(a) T; T=a; a=b; b=T;
#define SET(x,a) memset(x,a,sizeof(x))

//#define LIM
#ifdef LIM
	int S, D, Y;
	char *inp, *out, *ipos, *opos, DIG[30];
	#define FRMI inp=( char * )malloc( LIM*sizeof( char ) );fread_unlocked( inp,1,LIM,stdin );ipos=inp;
	#define FWM out=( char * )malloc( LIM*sizeof( char ) );opos=out;
	#define FWO fwrite_unlocked( out,opos-out,1,stdout );
        #define GETI(n) n=0;while(*ipos<33){ipos++;}if(*ipos=='-'){S=-1;ipos++;}else{S=1;}while(*ipos>='0'){n=10*n+(*ipos-'0');ipos++;}n*=S;
	#define PUTI(n) D=0;if(n<0){*opos++='-';n*=-1;}if(!n)*opos++='0';else{while(n){Y=n/10;DIG[D++]=n-Y*10+'0';n=Y;}\
	while(D--)*opos++=DIG[D];}
	#define PUTC(c) *opos++=c;
#endif

#define SQ(x) (x)*(x)
#define DIST( a,b ) ( SQ(a.x-b.x) + SQ(a.y-b.y) )
#define DISTI( a,b,c,d ) ( SQ(a+c) + SQ(b+d) )

using namespace std;
using namespace __gnu_cxx;

struct point {
	int x, y;
	int id;
};

bool comparex( point p, point q )
{
	return p.x < q.x;
}

bool comparey( point p, point q )
{
	return p.y < q.y;
}

point min_p1, min_p2;
int min_dist = INT_MAX;

void closest_pair( point *px, point *py, int n )
{
	int i, j;
	int d;

	if( n <= 3 ) {
		if( n >= 2 ) {
			FOR( i,0,n-2 ) {
				FOR( j,i+1,n-1 ) {
					if( ( d = DIST( px[i], px[j] ) ) < min_dist ) {
						min_dist = d;
						min_p1 = px[i];
						min_p2 = px[j];
					}
				}
			}
		}
	} else {
		int mid, divider;

		mid = n >> 1;

//		point pxl[mid+1], pxr[mid+1];
//		point pyl[mid+1], pyr[mid+1];
		point *pxl, *pxr;
		point *pyl, *pyr;
		pxl = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pxr = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pyl = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pyr = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );

		int pyl_len, pyr_len;

		FOR( i,0,mid ) {
			pxl[i] = px[i];
			if( mid+i+1 < n ) {
				pxr[i] = px[mid+i+1];
			}
		}

		divider = px[mid].x;
		pyl_len = pyr_len = 0;

		FOR( i,0,n-1 ) {
			if( py[i].x <= divider ) {
				pyl[pyl_len++] = py[i];
			} else {
				pyr[pyr_len++] = py[i];
			}
		}

		closest_pair( pxl, pyl, mid );
		closest_pair( pxr, pyr, n-mid-1 );

		point *pyd;
		pyd = ( struct point * )malloc( n*sizeof( struct point ) );
		int pyd_len = 0;

		FOR( i,0,n-1 ) {
			if( ABS( py[i].x-divider ) <= sqrt( min_dist ) ) {
				pyd[pyd_len++] = py[i];
			}
		}

		if( pyd_len > 1 ) {
			FOR( i,0,pyd_len-1 ) {
				for( j=i+1; j <= i+7 && j < pyd_len; j++ ) {
					if( ( d = DIST( pyd[i], pyd[j] ) ) < min_dist ) {
						min_dist = d;
						min_p1 = pyd[i];
						min_p2 = pyd[j];
					}
				}
			}
		}

		free( pyd );
		free (pxl );
		free( pxr );
		free( pyl );
		free( pyr );
	}
}

inline int version( int a, int b, int x, int y )
{
	if( a == x && b == y ) {
		return 1;
	} else if( a == -x && b == y ) {
		return 2;
	} else if( a == x && b == -y ) {
		return 3;
	} else {
		return 4;
	}
}

int main()
{
	int i, j;
	int n, m, a, b;
	point pt;

	freopen( "input.txt", "r", stdin );
	freopen( "output.txt", "w", stdout );

	scanf( "%d", &n );

//	m = n << 2;
//	point px[n], py[n],  temp[n];;

//	point *px, *py, *temp;

	point px[n], py[n];
	int ver[n];
//	px = ( struct point * )malloc( n*sizeof( struct point ) );
//	py = ( struct point * )malloc( n*sizeof( struct point ) );

	j = 0;

	FOR( i,0,n-1 ) {
		scanf( "%d%d", &a, &b );
		pt.x = ABS(a);
		pt.y = ABS(b);
		pt.id = i+1;
		ver[i] = version( a, b, pt.x, pt.y );
		px[j] = py[j] = pt;
		j++;
	}

	sort( px, px+j, comparex );
	sort( py, py+j, comparey );

	closest_pair( px, py, n );

//	cout << min_dist << endl;
	printf( "%d %d %d %d\n", min_p1.id, ver[min_p1.id-1], min_p2.id, 5-ver[min_p2.id-1] );

//	free( px );
//	free( py );

	return 0;
}


/*******************************************************************************************************************************************
* File Name   : j.cpp
* Development : Wed 19 Oct 2011 09:40:46 PM IST
* Author      : Xeronix
*******************************************************************************************************************************************/

#include <iostream>
#include <cstdio>
#include <vector>
#include <math.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <string.h>
#include <cstdlib>
#include <sstream>
#include <stack>
#include <queue>
#include <numeric>
#include <utility>
#include <cctype>
#include <list>
#include <limits.h>
#include <signal.h>
#include <time.h>
#include <map>
#include <set>
#include <float.h>

#define TR(c, i) for ( typeof((c).begin()) i = (c).begin(); i != (c).end(); i++ )
#define FOR(i, a, b) for ( i = a; i <= b; i++ )
#define ROF(i, a, b) for ( i = a; i >= b; i-- )
#define ALL(v) (v).begin(), (v).end()
#define SORT(v) sort( ALL(v) )
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#define ABS(a) ((a) < (0) ? (a)*(-1) : (a))
#define SWAP(a, b) typeof(a) T; T=a; a=b; b=T;
#define SET(x,a) memset(x,a,sizeof(x))

//#define LIM
#ifdef LIM
	int S, D, Y;
	char *inp, *out, *ipos, *opos, DIG[30];
	#define FRMI inp=( char * )malloc( LIM*sizeof( char ) );fread_unlocked( inp,1,LIM,stdin );ipos=inp;
	#define FWM out=( char * )malloc( LIM*sizeof( char ) );opos=out;
	#define FWO fwrite_unlocked( out,opos-out,1,stdout );
        #define GETI(n) n=0;while(*ipos<33){ipos++;}if(*ipos=='-'){S=-1;ipos++;}else{S=1;}while(*ipos>='0'){n=10*n+(*ipos-'0');ipos++;}n*=S;
	#define PUTI(n) D=0;if(n<0){*opos++='-';n*=-1;}if(!n)*opos++='0';else{while(n){Y=n/10;DIG[D++]=n-Y*10+'0';n=Y;}\
	while(D--)*opos++=DIG[D];}
	#define PUTC(c) *opos++=c;
#endif

#define SQ(x) (x)*(x)
#define DIST( a,b ) ( SQ(a.x-b.x) + SQ(a.y-b.y) )
#define DISTI( a,b,c,d ) ( SQ(a+c) + SQ(b+d) )

using namespace std;
using namespace __gnu_cxx;

struct point {
	int x, y;
	int id;
};

bool comparex( point p, point q )
{
	return p.x < q.x;
}

bool comparey( point p, point q )
{
	return p.y < q.y;
}

point min_p1, min_p2;
int min_dist = INT_MAX;

void closest_pair( point *px, point *py, int n )
{
	int i, j;
	int d;

	if( n <= 10 ) {
		if( n >= 2 ) {
			FOR( i,0,n-2 ) {
				FOR( j,i+1,n-1 ) {
					if( ( d = DIST( px[i], px[j] ) ) < min_dist ) {
						min_dist = d;
						min_p1 = px[i];
						min_p2 = px[j];
					}
				}
			}
		}
	} else {
		int mid, divider;

		mid = n >> 1;

//		point pxl[mid+1], pxr[mid+1];
//		point pyl[mid+1], pyr[mid+1];
		point *pxl, *pxr;
		point *pyl, *pyr;
		pxl = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pxr = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pyl = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );
		pyr = ( struct point * )malloc( (mid+1)*sizeof( struct point ) );

		int pyl_len, pyr_len;

		FOR( i,0,mid ) {
			pxl[i] = px[i];
			if( mid+i+1 < n ) {
				pxr[i] = px[mid+i+1];
			}
		}

		divider = px[mid].x;
		pyl_len = pyr_len = 0;

		FOR( i,0,n-1 ) {
			if( py[i].x <= divider ) {
				pyl[pyl_len++] = py[i];
			} else {
				pyr[pyr_len++] = py[i];
			}
		}

		closest_pair( pxl, pyl, mid );
		closest_pair( pxr, pyr, n-mid-1 );

		point *pyd;
		pyd = ( struct point * )malloc( n*sizeof( struct point ) );
		int pyd_len = 0;

		FOR( i,0,n-1 ) {
			if( ABS( py[i].x-divider ) <= sqrt( min_dist ) ) {
				pyd[pyd_len++] = py[i];
			}
		}

		if( pyd_len > 1 ) {
			FOR( i,0,pyd_len-1 ) {
				for( j=i+1; j <= i+7 && j < pyd_len; j++ ) {
					if( ( d = DIST( pyd[i], pyd[j] ) ) < min_dist ) {
						min_dist = d;
						min_p1 = pyd[i];
						min_p2 = pyd[j];
					}
				}
			}
		}

		free( pyd );
		free (pxl );
		free( pxr );
		free( pyl );
		free( pyr );
	}
}

inline int version( int a, int b, int x, int y )
{
	if( a == x && b == y ) {
		return 1;
	} else if( a == -x && b == y ) {
		return 2;
	} else if( a == x && b == -y ) {
		return 3;
	} else {
		return 4;
	}
}

int main()
{
	int i, j;
	int n, m, a, b;
	point pt;

	freopen( "input.txt", "r", stdin );
	freopen( "output.txt", "w", stdout );

	scanf( "%d", &n );

	point *px, *py;
	int *ver;

//	point px[n], py[n];
//	int ver[n];
	px = ( struct point * )malloc( n*sizeof( struct point ) );
	py = ( struct point * )malloc( n*sizeof( struct point ) );
	ver = ( int * )malloc( n*sizeof( int ) );

	j = 0;

	FOR( i,0,n-1 ) {
		scanf( "%d%d", &a, &b );
		pt.x = ABS(a);
		pt.y = ABS(b);
		pt.id = i+1;
		ver[i] = version( a, b, pt.x, pt.y );
		px[j] = py[j] = pt;
		j++;
	}

	sort( px, px+j, comparex );
	sort( py, py+j, comparey );

	closest_pair( px, py, n );

	printf( "%d %d %d %d\n", min_p1.id, ver[min_p1.id-1], min_p2.id, 5-ver[min_p2.id-1] );

	free( px );
	free( py );
	free( ver );

	return 0;
}