/*******************************************************************************************************************************************
* 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;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cstring>
#include <fstream>

using namespace std;

#define F first
#define PB(v,x) v.push_back(x)
#define size(X) (int)X.size()
#define S second
#define show(X) cerr << #X << " = " << X << endl;
#define getrandom(min,max) \
    ((rand()%(int)(((max)+1)-(min)))+min)
#define foreach(var, container) \
    for(typeof((container).begin()) var = (container).begin(); \
            var != (container).end(); \
            ++var)
#define SetBit(value, place) ((value) | (1 << (place)))
#define ClearBit(value, place) ((value) & (~(1 << (place))))
#define ToggleBit(value, place) ((value) ^ (1 << (place)))
#define GetBit(value, place) (((value) >> (place)) & 1)
#define GetPrecentage(Numerator, Denominator)   ((Numerator)*100.0/(Denominator))
#define GI ({int t;scanf("%d",&t);t;})
#define GL ({LL t;scanf("%lld",&t);t;})
#define GD ({double t;scanf("%lf",&t);t;})
#define is istringstream
#define os ostringstream
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define REP(i,n) for (int i=0,_n=(n); i < _n; i++)
#define REV(i,n) for (int i=(n)-1; i >= 0; i--)
#define FOR(i,a,b) for (int _b=(b), i=(a); i < _b; i++)
#define ROR(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))
#define CLEAR(x) memset(x,0,sizeof x);
#define REVERSE(c) reverse(ALL(c))
#define UNIQUE(c) SORT(c),(c).resize(unique(ALL(c))-(c).begin())
#define INF (int)1e9
#define eps 1.0e-11
#define PI(x) printf("%d ",x)
#define two(x) ((x)*(x))
template <class X> void printa(X a,int n)
{
    REP(i,n) cerr << a[i] << " " ;
    cerr << endl;
}

template <class X> void printv(X v)
{
    foreach(it,v) cerr << *it << " " ;
    cerr << endl;
}
typedef pair<int,int> pii;
typedef long long ll;
typedef pair<ll,ll> pll;
map<pii,pii> mp;
map<pii,int> sit;
ifstream fin("input.txt");
ofstream fout("output.txt");

struct point {
    int x,y;
    point(){;}
};

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

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

const int MAXN = (int)1e5 + 100;
point p[MAXN];
int n;
point ANS1,ANS2;

void input()
{
    fin >> n;
    REP(i,n)
    {
        fin >> p[i].x >> p[i].y;
        point l = p[i];
        if(l.x < 0) l.x *=-1;
        if(l.y < 0) l.y *=-1;
        if(mp.find(pii(l.x,l.y))!=mp.end())
        {
            fout << i << " " << sit[pii(p[i].x/l.x * -1,p[i].y/l.y * -1)] << " "<< mp[pii(l.x,l.y)].F << " " << mp[pii(l.x,l.y)].S << endl;
            exit(0);
        }
        int k1 = 1 , k2 = 1;
        if(l.x!=0) k1 = l.x / p[i].x;
        if(l.y != 0) k2 = l.y / p[i].y;
        mp[pii(l.x,l.y)] = pii(i+1,sit[pii(k1,k2)]);
        p[i] = l;
    }
    sort(p,p+n,cmp1);
}

double Conquer(int s,int e,double d)
{
    int m = (s+e)/2;
    double X = p[m].x;
    vector<point> v;
    FOR(i,s,e) if(abs((double)p[i].x - X) <= d) PB(v,p[i]);
    sort(v.begin(),v.end(),cmp2);
    REVERSE(v);
    int start = 0;
    double ret = d;
    REP(i,size(v))
    {
        while(abs(v[i].y - v[start].y) > d) start++;
        FOR(j,start,i)
        {
            if(ret >= sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y))))
            {
                ret = sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y)));
                ANS1 = v[i];
                ANS2 = v[j];
            }
        }
    }
    return ret;
}

double Divide(int s,int e)
{
    if(s==e-1) return INF;
    int m = (s+e)/2;
    double d1 = Divide(s,m);
    double d2 = Divide(m,e);
    double d = min(d1,d2);
    return Conquer(s,e,d);
}

int main()
{
    sit[pii(1,1)] = 1;
    sit[pii(-1,1)] = 2;
    sit[pii(1,-1)] = 3;
    sit[pii(-1,-1)] = 4;
    input();
    Divide(0,n);
    pii a1 = pii(ANS1.x,ANS1.y);
    pii a2 = pii(ANS2.x,ANS2.y);
    int k = mp[a1].S;
    if(k==1) k = 4;
    else if(k==4) k = 1;
    else if(k==2) k = 3;
    else if(k==3) k = 2;
    fout << mp[a1].F << " " << k << " " << mp[a2].F << " " << mp[a2].S << endl;
    return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cstring>
#include <fstream>

using namespace std;

#define F first
#define PB(v,x) v.push_back(x)
#define size(X) (int)X.size()
#define S second
#define show(X) cerr << #X << " = " << X << endl;
#define getrandom(min,max) \
    ((rand()%(int)(((max)+1)-(min)))+min)
#define foreach(var, container) \
    for(typeof((container).begin()) var = (container).begin(); \
            var != (container).end(); \
            ++var)
#define SetBit(value, place) ((value) | (1 << (place)))
#define ClearBit(value, place) ((value) & (~(1 << (place))))
#define ToggleBit(value, place) ((value) ^ (1 << (place)))
#define GetBit(value, place) (((value) >> (place)) & 1)
#define GetPrecentage(Numerator, Denominator)   ((Numerator)*100.0/(Denominator))
#define GI ({int t;scanf("%d",&t);t;})
#define GL ({LL t;scanf("%lld",&t);t;})
#define GD ({double t;scanf("%lf",&t);t;})
#define is istringstream
#define os ostringstream
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define REP(i,n) for (int i=0,_n=(n); i < _n; i++)
#define REV(i,n) for (int i=(n)-1; i >= 0; i--)
#define FOR(i,a,b) for (int _b=(b), i=(a); i < _b; i++)
#define ROR(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))
#define CLEAR(x) memset(x,0,sizeof x);
#define REVERSE(c) reverse(ALL(c))
#define UNIQUE(c) SORT(c),(c).resize(unique(ALL(c))-(c).begin())
#define INF (int)1e9
#define eps 1.0e-11
#define PI(x) printf("%d ",x)
#define two(x) ((x)*(x))
template <class X> void printa(X a,int n)
{
    REP(i,n) cerr << a[i] << " " ;
    cerr << endl;
}

template <class X> void printv(X v)
{
    foreach(it,v) cerr << *it << " " ;
    cerr << endl;
}
typedef pair<int,int> pii;
typedef long long ll;
typedef pair<ll,ll> pll;
map<pii,pii> mp;
map<pii,int> sit;
ifstream fin("input.txt");
ofstream fout("output.txt");

struct point {
    int x,y;
    point(){;}
};

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

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

const int MAXN = (int)1e5 + 100;
point p[MAXN];
int n;
point ANS1,ANS2;
double ALL = INF;

void input()
{
    fin >> n;
    REP(i,n)
    {
        fin >> p[i].x >> p[i].y;
        point l = p[i];
        if(l.x < 0) l.x *=-1;
        if(l.y < 0) l.y *=-1;
        if(mp.find(pii(l.x,l.y))!=mp.end())
        {
            fout << i << " " << sit[pii(p[i].x/l.x * -1,p[i].y/l.y * -1)] << " "<< mp[pii(l.x,l.y)].F << " " << mp[pii(l.x,l.y)].S << endl;
            exit(0);
        }
        int k1 = 1 , k2 = 1;
        if(l.x!=0) k1 = l.x / p[i].x;
        if(l.y != 0) k2 = l.y / p[i].y;
        mp[pii(l.x,l.y)] = pii(i+1,sit[pii(k1,k2)]);
        p[i] = l;
    }
    sort(p,p+n,cmp1);
}

double Conquer(int s,int e,double d)
{
    int m = (s+e)/2;
    double X = p[m].x;
    vector<point> v;
    FOR(i,s,e) if(abs((double)p[i].x - X) <= d) PB(v,p[i]);
    sort(v.begin(),v.end(),cmp2);
    REVERSE(v);
    int start = 0;
    double ret = d;
    REP(i,size(v))
    {
        while(abs(v[i].y - v[start].y) > d) start++;
        FOR(j,start,i)
        {
            if(ret > sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y))))
            {
                ret = sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y)));
                if(ALL > ret)
                {
                    ALL = ret;
                    ANS1 = v[i];
                    ANS2 = v[j];
                }
            }
        }
    }
    return ret;
}

double Divide(int s,int e)
{
    if(s==e-1) return INF;
    int m = (s+e)/2;
    double d1 = Divide(s,m);
    double d2 = Divide(m,e);
    double d = min(d1,d2);
    return Conquer(s,e,d);
}

int main()
{
    sit[pii(1,1)] = 1;
    sit[pii(-1,1)] = 2;
    sit[pii(1,-1)] = 3;
    sit[pii(-1,-1)] = 4;
    input();
    Divide(0,n);
    pii a1 = pii(ANS1.x,ANS1.y);
    pii a2 = pii(ANS2.x,ANS2.y);
    int k = mp[a1].S;
    if(k==1) k = 4;
    else if(k==4) k = 1;
    else if(k==2) k = 3;
    else if(k==3) k = 2;
    fout << mp[a1].F << " " << k << " " << mp[a2].F << " " << mp[a2].S << endl;
    return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cstring>
#include <fstream>

using namespace std;

#define F first
#define PB(v,x) v.push_back(x)
#define size(X) (int)X.size()
#define S second
#define show(X) cerr << #X << " = " << X << endl;
#define getrandom(min,max) \
	((rand()%(int)(((max)+1)-(min)))+min)
#define foreach(var, container) \
	for(typeof((container).begin()) var = (container).begin(); \
			var != (container).end(); \
			++var)
#define SetBit(value, place) ((value) | (1 << (place)))
#define ClearBit(value, place) ((value) & (~(1 << (place))))
#define ToggleBit(value, place) ((value) ^ (1 << (place)))
#define GetBit(value, place) (((value) >> (place)) & 1)
#define GetPrecentage(Numerator, Denominator)	((Numerator)*100.0/(Denominator))
#define GI ({int t;scanf("%d",&t);t;})
#define GL ({LL t;scanf("%lld",&t);t;})
#define GD ({double t;scanf("%lf",&t);t;})
#define is istringstream
#define os ostringstream
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define REP(i,n) for (int i=0,_n=(n); i < _n; i++)
#define REV(i,n) for (int i=(n)-1; i >= 0; i--)
#define FOR(i,a,b) for (int _b=(b), i=(a); i < _b; i++)
#define ROR(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))
#define CLEAR(x) memset(x,0,sizeof x);
#define REVERSE(c) reverse(ALL(c))
#define UNIQUE(c) SORT(c),(c).resize(unique(ALL(c))-(c).begin())
#define INF (int)1e9
#define eps 1.0e-11
#define PI(x) printf("%d ",x)
#define two(x) ((x)*(x))
template <class X> void printa(X a,int n)
{
	REP(i,n) cerr << a[i] << " " ;
	cerr << endl;
}

template <class X> void printv(X v)
{
	foreach(it,v) cerr << *it << " " ;
	cerr << endl;
}
typedef pair<int,int> pii;
typedef long long ll;
typedef pair<ll,ll> pll;
map<pii,pii> mp;
map<pii,int> sit;
ifstream fin("input.txt");
ofstream fout("output.txt");

struct point {
	int x,y;
	point(){;}
};

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

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

const int MAXN = (int)1e5 + 100;
point p[MAXN];
int n;
point ANS1,ANS2;

void input()
{
	fin >> n;
	REP(i,n)
	{
		fin >> p[i].x >> p[i].y;
		point l = p[i];
		if(l.x < 0) l.x *=-1;
		if(l.y < 0) l.y *=-1;
		if(mp.find(pii(l.x,l.y))!=mp.end())
		{
			fout << i << " " << sit[pii(p[i].x/l.x * -1,p[i].y/l.y * -1)] << " "<< mp[pii(l.x,l.y)].F << " " << mp[pii(l.x,l.y)].S << endl;
			exit(0);
		}
		int k1 = -1 , k2 = -1;
		if(l.x!=0) k1 = l.x / p[i].x;
		if(l.y != 0) k2 = l.y / p[i].y;
		mp[pii(l.x,l.y)] = pii(i+1,sit[pii(k1,k2)]);
		p[i] = l;
	}
	sort(p,p+n,cmp1);
}

double Conquer(int s,int e,double d)
{
	int m = (s+e)/2;
	double X = p[m].x;
	vector<point> v;
	FOR(i,s,e) if(abs((double)p[i].x - X) <= d) PB(v,p[i]);
	sort(v.begin(),v.end(),cmp2);
	REVERSE(v);
	int start = 0;
	double ret = d;
	REP(i,size(v))
	{
		while(abs(v[i].y - v[start].y) > d) start++;
		FOR(j,start,i)
		{
			if(ret > sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y))))
			{
				ret = sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y)));
				ANS1 = v[i];
				ANS2 = v[j];
			}
		}
	}
	return ret;
}

double Divide(int s,int e)
{
	if(s==e-1) return INF;
	int m = (s+e)/2;
	double d1 = Divide(s,m);
	double d2 = Divide(m,e);
	double d = min(d1,d2);
	return Conquer(s,e,d);
}

int main()
{
	sit[pii(1,1)] = 1;
	sit[pii(-1,1)] = 2;
	sit[pii(1,-1)] = 3;
	sit[pii(-1,-1)] = 4;
	input();
	Divide(0,n);
	pii a1 = pii(ANS1.x,ANS1.y);
	pii a2 = pii(ANS2.x,ANS2.y);
	int k = mp[a1].S;
	if(k==1) k = 4;
	if(k==4) k = 1;
	if(k==2) k = 3;
	if(k==3) k = 2;
	fout << mp[a1].F << " " << k << " " << mp[a2].F << " " << mp[a2].S << endl;
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cstring>
#include <fstream>

using namespace std;

#define F first
#define PB(v,x) v.push_back(x)
#define size(X) (int)X.size()
#define S second
#define show(X) cerr << #X << " = " << X << endl;
#define getrandom(min,max) \
	((rand()%(int)(((max)+1)-(min)))+min)
#define foreach(var, container) \
	for(typeof((container).begin()) var = (container).begin(); \
			var != (container).end(); \
			++var)
#define SetBit(value, place) ((value) | (1 << (place)))
#define ClearBit(value, place) ((value) & (~(1 << (place))))
#define ToggleBit(value, place) ((value) ^ (1 << (place)))
#define GetBit(value, place) (((value) >> (place)) & 1)
#define GetPrecentage(Numerator, Denominator)	((Numerator)*100.0/(Denominator))
#define GI ({int t;scanf("%d",&t);t;})
#define GL ({LL t;scanf("%lld",&t);t;})
#define GD ({double t;scanf("%lf",&t);t;})
#define is istringstream
#define os ostringstream
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define REP(i,n) for (int i=0,_n=(n); i < _n; i++)
#define REV(i,n) for (int i=(n)-1; i >= 0; i--)
#define FOR(i,a,b) for (int _b=(b), i=(a); i < _b; i++)
#define ROR(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))
#define CLEAR(x) memset(x,0,sizeof x);
#define REVERSE(c) reverse(ALL(c))
#define UNIQUE(c) SORT(c),(c).resize(unique(ALL(c))-(c).begin())
#define INF (int)1e9
#define eps 1.0e-11
#define PI(x) printf("%d ",x)
#define two(x) ((x)*(x))
template <class X> void printa(X a,int n)
{
	REP(i,n) cerr << a[i] << " " ;
	cerr << endl;
}

template <class X> void printv(X v)
{
	foreach(it,v) cerr << *it << " " ;
	cerr << endl;
}
typedef pair<int,int> pii;
typedef long long ll;
typedef pair<ll,ll> pll;
map<pii,pii> mp;
map<pii,int> sit;
ifstream fin("input.txt");
ofstream fout("output.txt");

struct point {
	int x,y;
	point(){;}
};

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

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

const int MAXN = (int)1e5 + 100;
point p[MAXN];
int n;
point ANS1,ANS2;
double ALL = INF;

void input()
{
	fin >> n;
	REP(i,n)
	{
		fin >> p[i].x >> p[i].y;
		point l = p[i];
		if(l.x < 0) l.x *=-1;
		if(l.y < 0) l.y *=-1;
		if(mp.find(pii(l.x,l.y))!=mp.end())
		{
			fout << i << " " << sit[pii(p[i].x/l.x * -1,p[i].y/l.y * -1)] << " "<< mp[pii(l.x,l.y)].F << " " << mp[pii(l.x,l.y)].S << endl;
			exit(0);
		}
		int k1 = 1 , k2 = 1;
		if(l.x!=0) k1 = l.x / p[i].x;
		if(l.y != 0) k2 = l.y / p[i].y;
		mp[pii(l.x,l.y)] = pii(i+1,sit[pii(k1,k2)]);
		p[i] = l;
	}
	sort(p,p+n,cmp1);
}

double Conquer(int s,int e,double d)
{
	int m = (s+e)/2;
	double X = p[m].x;
	vector<point> v;
	FOR(i,s,e) if(abs((double)p[i].x - X) <= d) PB(v,p[i]);
	sort(v.begin(),v.end(),cmp2);
	REVERSE(v);
	int start = 0;
	double ret = d;
	REP(i,size(v))
	{
		while(abs(v[i].y - v[start].y) > d) start++;
		FOR(j,start,i)
		{
			if(ret > sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y))))
			{
				ret = sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y)));
				if(ALL > ret)
				{
					ALL = ret;
					ANS1 = v[i];
					ANS2 = v[j];
				}
			}
		}
	}
	return ret;
}

double Divide(int s,int e)
{
	if(s==e-1) return INF;
	int m = (s+e)/2;
	double d1 = Divide(s,m);
	double d2 = Divide(m,e);
	double d = min(d1,d2);
	return Conquer(s,e,d);
}

int main()
{
	sit[pii(1,1)] = 1;
	sit[pii(-1,1)] = 2;
	sit[pii(1,-1)] = 3;
	sit[pii(-1,-1)] = 4;
	input();
	Divide(0,n);
	pii a1 = pii(ANS1.x,ANS1.y);
	pii a2 = pii(ANS2.x,ANS2.y);
	int k = mp[a1].S;
	if(k==1) k = 4;
	else if(k==4) k = 1;
	else if(k==2) k = 3;
	else if(k==3) k = 2;
	fout << mp[a1].F << " " << k << " " << mp[a2].F << " " << mp[a2].S << endl;
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cstring>
#include <fstream>

using namespace std;

#define F first
#define PB(v,x) v.push_back(x)
#define size(X) (int)X.size()
#define S second
#define show(X) cerr << #X << " = " << X << endl;
#define getrandom(min,max) \
	((rand()%(int)(((max)+1)-(min)))+min)
#define foreach(var, container) \
	for(typeof((container).begin()) var = (container).begin(); \
			var != (container).end(); \
			++var)
#define SetBit(value, place) ((value) | (1 << (place)))
#define ClearBit(value, place) ((value) & (~(1 << (place))))
#define ToggleBit(value, place) ((value) ^ (1 << (place)))
#define GetBit(value, place) (((value) >> (place)) & 1)
#define GetPrecentage(Numerator, Denominator)	((Numerator)*100.0/(Denominator))
#define GI ({int t;scanf("%d",&t);t;})
#define GL ({LL t;scanf("%lld",&t);t;})
#define GD ({double t;scanf("%lf",&t);t;})
#define is istringstream
#define os ostringstream
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define REP(i,n) for (int i=0,_n=(n); i < _n; i++)
#define REV(i,n) for (int i=(n)-1; i >= 0; i--)
#define FOR(i,a,b) for (int _b=(b), i=(a); i < _b; i++)
#define ROR(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))
#define CLEAR(x) memset(x,0,sizeof x);
#define REVERSE(c) reverse(ALL(c))
#define UNIQUE(c) SORT(c),(c).resize(unique(ALL(c))-(c).begin())
#define INF (int)1e9
#define eps 1.0e-11
#define PI(x) printf("%d ",x)
#define two(x) ((x)*(x))
template <class X> void printa(X a,int n)
{
	REP(i,n) cerr << a[i] << " " ;
	cerr << endl;
}

template <class X> void printv(X v)
{
	foreach(it,v) cerr << *it << " " ;
	cerr << endl;
}
typedef pair<int,int> pii;
typedef long long ll;
typedef pair<ll,ll> pll;
map<pii,pii> mp;
map<pii,int> sit;
ifstream fin("input.txt");
ofstream fout("output.txt");

struct point {
	int x,y;
	point(){;}
};

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

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

const int MAXN = (int)1e5 + 100;
point p[MAXN];
int n;
point ANS1,ANS2;

void input()
{
	fin >> n;
	REP(i,n)
	{
		fin >> p[i].x >> p[i].y;
		point l = p[i];
		if(l.x < 0) l.x *=-1;
		if(l.y < 0) l.y *=-1;
		if(mp.find(pii(l.x,l.y))!=mp.end())
		{
			fout << i << " " << sit[pii(p[i].x/l.x * -1,p[i].y/l.y * -1)] << " "<< mp[pii(l.x,l.y)].F << " " << mp[pii(l.x,l.y)].S << endl;
			exit(0);
		}
		int k1 = 1 , k2 = 1;
		if(l.x!=0) k1 = l.x / p[i].x;
		if(l.y != 0) k2 = l.y / p[i].y;
		mp[pii(l.x,l.y)] = pii(i+1,sit[pii(k1,k2)]);
		p[i] = l;
	}
	sort(p,p+n,cmp1);
}

double Conquer(int s,int e,double d)
{
	int m = (s+e)/2;
	double X = p[m].x;
	vector<point> v;
	FOR(i,s,e) if(abs((double)p[i].x - X) <= d) PB(v,p[i]);
	sort(v.begin(),v.end(),cmp2);
	REVERSE(v);
	int start = 0;
	double ret = d;
	REP(i,size(v))
	{
		while(abs(v[i].y - v[start].y) > d) start++;
		FOR(j,start,i)
		{
			if(ret >= sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y))))
			{
				ret = sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y)));
				ANS1 = v[i];
				ANS2 = v[j];
			}
		}
	}
	return ret;
}

double Divide(int s,int e)
{
	if(s==e-1) return INF;
	int m = (s+e)/2;
	double d1 = Divide(s,m);
	double d2 = Divide(m,e);
	double d = min(d1,d2);
	return Conquer(s,e,d);
}

int main()
{
	sit[pii(1,1)] = 1;
	sit[pii(-1,1)] = 2;
	sit[pii(1,-1)] = 3;
	sit[pii(-1,-1)] = 4;
	input();
	Divide(0,n);
	pii a1 = pii(ANS1.x,ANS1.y);
	pii a2 = pii(ANS2.x,ANS2.y);
	int k = mp[a1].S;
	if(k==1) k = 4;
	else if(k==4) k = 1;
	else if(k==2) k = 3;
	else if(k==3) k = 2;
	fout << mp[a1].F << " " << k << " " << mp[a2].F << " " << mp[a2].S << endl;
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cstring>
#include <fstream>

using namespace std;

#define F first
#define PB(v,x) v.push_back(x)
#define size(X) (int)X.size()
#define S second
#define show(X) cerr << #X << " = " << X << endl;
#define getrandom(min,max) \
	((rand()%(int)(((max)+1)-(min)))+min)
#define foreach(var, container) \
	for(typeof((container).begin()) var = (container).begin(); \
			var != (container).end(); \
			++var)
#define SetBit(value, place) ((value) | (1 << (place)))
#define ClearBit(value, place) ((value) & (~(1 << (place))))
#define ToggleBit(value, place) ((value) ^ (1 << (place)))
#define GetBit(value, place) (((value) >> (place)) & 1)
#define GetPrecentage(Numerator, Denominator)	((Numerator)*100.0/(Denominator))
#define GI ({int t;scanf("%d",&t);t;})
#define GL ({LL t;scanf("%lld",&t);t;})
#define GD ({double t;scanf("%lf",&t);t;})
#define is istringstream
#define os ostringstream
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define REP(i,n) for (int i=0,_n=(n); i < _n; i++)
#define REV(i,n) for (int i=(n)-1; i >= 0; i--)
#define FOR(i,a,b) for (int _b=(b), i=(a); i < _b; i++)
#define ROR(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))
#define CLEAR(x) memset(x,0,sizeof x);
#define REVERSE(c) reverse(ALL(c))
#define UNIQUE(c) SORT(c),(c).resize(unique(ALL(c))-(c).begin())
#define INF (int)1e9
#define eps 1.0e-11
#define PI(x) printf("%d ",x)
#define two(x) ((x)*(x))
template <class X> void printa(X a,int n)
{
	REP(i,n) cerr << a[i] << " " ;
	cerr << endl;
}

template <class X> void printv(X v)
{
	foreach(it,v) cerr << *it << " " ;
	cerr << endl;
}
typedef pair<int,int> pii;
typedef long long ll;
typedef pair<ll,ll> pll;
map<pii,pii> mp;
map<pii,int> sit;
ifstream fin("input.txt");
ofstream fout("output.txt");

struct point {
	int x,y;
	point(){;}
};

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

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

const int MAXN = (int)1e5 + 100;
point p[MAXN];
int n;
point ANS1,ANS2;
double ALL = INF;

void input()
{
	fin >> n;
	REP(i,n)
	{
		fin >> p[i].x >> p[i].y;
		point l = p[i];
		if(l.x < 0) l.x *=-1;
		if(l.y < 0) l.y *=-1;
		if(mp.find(pii(l.x,l.y))!=mp.end())
		{
			cout << i << " " << sit[pii(p[i].x/l.x * -1,p[i].y/l.y * -1)] << " "<< mp[pii(l.x,l.y)].F << " " << mp[pii(l.x,l.y)].S << endl;
			exit(0);
		}
		int k1 = 1 , k2 = 1;
		if(l.x!=0) k1 = l.x / p[i].x;
		if(l.y != 0) k2 = l.y / p[i].y;
		mp[pii(l.x,l.y)] = pii(i+1,sit[pii(k1,k2)]);
		p[i] = l;
	}
	sort(p,p+n,cmp1);
}

double Conquer(int s,int e,double d)
{
	int m = (s+e)/2;
	double X = p[m].x;
	vector<point> v;
	FOR(i,s,e) if(abs((double)p[i].x - X) <= d) PB(v,p[i]);
	sort(v.begin(),v.end(),cmp2);
	REVERSE(v);
	int start = 0;
	double ret = d;
	REP(i,size(v))
	{
		while(abs(v[i].y - v[start].y) > d) start++;
		FOR(j,start,i)
		{
			if(ret > sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y))))
			{
				ret = sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y)));
				if(ALL > ret)
				{
					ALL = ret;
					ANS1 = v[i];
					ANS2 = v[j];
				}
			}
		}
	}
	return ret;
}

double Divide(int s,int e)
{
	if(s==e-1) return INF;
	int m = (s+e)/2;
	double d1 = Divide(s,m);
	double d2 = Divide(m,e);
	double d = min(d1,d2);
	return Conquer(s,e,d);
}

int main()
{
	sit[pii(1,1)] = 1;
	sit[pii(-1,1)] = 2;
	sit[pii(1,-1)] = 3;
	sit[pii(-1,-1)] = 4;
	input();
	Divide(0,n);
	pii a1 = pii(ANS1.x,ANS1.y);
	pii a2 = pii(ANS2.x,ANS2.y);
	int k = mp[a1].S;
	if(k==1) k = 4;
	else if(k==4) k = 1;
	else if(k==2) k = 3;
	else if(k==3) k = 2;
	fout << mp[a1].F << " " << k << " " << mp[a2].F << " " << mp[a2].S << endl;
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cstring>
#include <fstream>

using namespace std;

#define F first
#define PB(v,x) v.push_back(x)
#define size(X) (int)X.size()
#define S second
#define show(X) cerr << #X << " = " << X << endl;
#define getrandom(min,max) \
    ((rand()%(int)(((max)+1)-(min)))+min)
#define foreach(var, container) \
    for(typeof((container).begin()) var = (container).begin(); \
            var != (container).end(); \
            ++var)
#define SetBit(value, place) ((value) | (1 << (place)))
#define ClearBit(value, place) ((value) & (~(1 << (place))))
#define ToggleBit(value, place) ((value) ^ (1 << (place)))
#define GetBit(value, place) (((value) >> (place)) & 1)
#define GetPrecentage(Numerator, Denominator)   ((Numerator)*100.0/(Denominator))
#define GI ({int t;scanf("%d",&t);t;})
#define GL ({LL t;scanf("%lld",&t);t;})
#define GD ({double t;scanf("%lf",&t);t;})
#define is istringstream
#define os ostringstream
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define REP(i,n) for (int i=0,_n=(n); i < _n; i++)
#define REV(i,n) for (int i=(n)-1; i >= 0; i--)
#define FOR(i,a,b) for (int _b=(b), i=(a); i < _b; i++)
#define ROR(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))
#define CLEAR(x) memset(x,0,sizeof x);
#define REVERSE(c) reverse(ALL(c))
#define UNIQUE(c) SORT(c),(c).resize(unique(ALL(c))-(c).begin())
#define INF (int)1e9
#define eps 1.0e-11
#define PI(x) printf("%d ",x)
#define two(x) ((x)*(x))
template <class X> void printa(X a,int n)
{
    REP(i,n) cerr << a[i] << " " ;
    cerr << endl;
}

template <class X> void printv(X v)
{
    foreach(it,v) cerr << *it << " " ;
    cerr << endl;
}
typedef pair<int,int> pii;
typedef long long ll;
typedef pair<ll,ll> pll;
map<pii,pii> mp;
map<pii,int> sit;
ifstream fin("input.txt");
ofstream fout("output.txt");

struct point {
    int x,y;
    point(){;}
};

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

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

const int MAXN = (int)1e5 + 100;
point p[MAXN];
int n;
point ANS1,ANS2;
double ALL = INF;

void input()
{
    fin >> n;
    REP(i,n)
    {
        fin >> p[i].x >> p[i].y;
        point l = p[i];
        if(l.x < 0) l.x *=-1;
        if(l.y < 0) l.y *=-1;
        if(mp.find(pii(l.x,l.y))!=mp.end())
        {
            fout << i << " " << sit[pii(p[i].x/l.x * -1,p[i].y/l.y * -1)] << " "<< mp[pii(l.x,l.y)].F << " " << mp[pii(l.x,l.y)].S << endl;
            exit(1);
        }
        int k1 = 1 , k2 = 1;
        if(l.x!=0) k1 = l.x / p[i].x;
        if(l.y != 0) k2 = l.y / p[i].y;
        mp[pii(l.x,l.y)] = pii(i+1,sit[pii(k1,k2)]);
        p[i] = l;
    }
    sort(p,p+n,cmp1);
}

double Conquer(int s,int e,double d)
{
    int m = (s+e)/2;
    double X = p[m].x;
    vector<point> v;
    FOR(i,s,e) if(abs((double)p[i].x - X) <= d) PB(v,p[i]);
    sort(v.begin(),v.end(),cmp2);
    REVERSE(v);
    int start = 0;
    double ret = d;
    REP(i,size(v))
    {
        while(abs(v[i].y - v[start].y) > d) start++;
        FOR(j,start,i)
        {
            if(ret > sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y))))
            {
                ret = sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y)));
                if(ALL > ret)
                {
                    ALL = ret;
                    ANS1 = v[i];
                    ANS2 = v[j];
                }
            }
        }
    }
    return ret;
}

double Divide(int s,int e)
{
    if(s==e-1) return INF;
    int m = (s+e)/2;
    double d1 = Divide(s,m);
    double d2 = Divide(m,e);
    double d = min(d1,d2);
    return Conquer(s,e,d);
}

int main()
{
    sit[pii(1,1)] = 1;
    sit[pii(-1,1)] = 2;
    sit[pii(1,-1)] = 3;
    sit[pii(-1,-1)] = 4;
    input();
    Divide(0,n);
    pii a1 = pii(ANS1.x,ANS1.y);
    pii a2 = pii(ANS2.x,ANS2.y);
    int k = mp[a1].S;
    if(k==1) k = 4;
    else if(k==4) k = 1;
    else if(k==2) k = 3;
    else if(k==3) k = 2;
    fout << mp[a1].F << " " << k << " " << mp[a2].F << " " << mp[a2].S << endl;
    return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cstring>
#include <fstream>

using namespace std;

#define F first
#define PB(v,x) v.push_back(x)
#define size(X) (int)X.size()
#define S second
#define show(X) cerr << #X << " = " << X << endl;
#define getrandom(min,max) \
    ((rand()%(int)(((max)+1)-(min)))+min)
#define foreach(var, container) \
    for(typeof((container).begin()) var = (container).begin(); \
            var != (container).end(); \
            ++var)
#define SetBit(value, place) ((value) | (1 << (place)))
#define ClearBit(value, place) ((value) & (~(1 << (place))))
#define ToggleBit(value, place) ((value) ^ (1 << (place)))
#define GetBit(value, place) (((value) >> (place)) & 1)
#define GetPrecentage(Numerator, Denominator)   ((Numerator)*100.0/(Denominator))
#define GI ({int t;scanf("%d",&t);t;})
#define GL ({LL t;scanf("%lld",&t);t;})
#define GD ({double t;scanf("%lf",&t);t;})
#define is istringstream
#define os ostringstream
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define REP(i,n) for (int i=0,_n=(n); i < _n; i++)
#define REV(i,n) for (int i=(n)-1; i >= 0; i--)
#define FOR(i,a,b) for (int _b=(b), i=(a); i < _b; i++)
#define ROR(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))
#define CLEAR(x) memset(x,0,sizeof x);
#define REVERSE(c) reverse(ALL(c))
#define UNIQUE(c) SORT(c),(c).resize(unique(ALL(c))-(c).begin())
#define INF (int)1e9
#define eps 1.0e-11
#define PI(x) printf("%d ",x)
#define two(x) ((x)*(x))
template <class X> void printa(X a,int n)
{
    REP(i,n) cerr << a[i] << " " ;
    cerr << endl;
}

template <class X> void printv(X v)
{
    foreach(it,v) cerr << *it << " " ;
    cerr << endl;
}
typedef pair<int,int> pii;
typedef long long ll;
typedef pair<ll,ll> pll;
map<pii,pii> mp;
map<pii,int> sit;
ifstream fin("input.txt");
ofstream fout("output.txt");

struct point {
    int x,y;
    point(){;}
};

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

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

const int MAXN = (int)1e5 + 100;
point p[MAXN];
int n;
point ANS1,ANS2;
double ALL = INF;

void input()
{
    fin >> n;
    REP(i,n)
    {
        fin >> p[i].x >> p[i].y;
        point l = p[i];
        if(l.x < 0) l.x *=-1;
        if(l.y < 0) l.y *=-1;
        if(mp.find(pii(l.x,l.y))!=mp.end())
        {
            fout << i+1 << " " << sit[pii(p[i].x/l.x * -1,p[i].y/l.y * -1)] << " "<< mp[pii(l.x,l.y)].F << " " << mp[pii(l.x,l.y)].S << endl;
            exit(0);
        }
        int k1 = 1 , k2 = 1;
        if(l.x!=0) k1 = l.x / p[i].x;
        if(l.y != 0) k2 = l.y / p[i].y;
        mp[pii(l.x,l.y)] = pii(i+1,sit[pii(k1,k2)]);
        p[i] = l;
    }
    sort(p,p+n,cmp1);
}

double Conquer(int s,int e,double d)
{
    int m = (s+e)/2;
    double X = p[m].x;
    vector<point> v;
    FOR(i,s,e) if(abs((double)p[i].x - X) <= d) PB(v,p[i]);
    sort(v.begin(),v.end(),cmp2);
    REVERSE(v);
    int start = 0;
    double ret = d;
    REP(i,size(v))
    {
        while(abs(v[i].y - v[start].y) > d) start++;
        FOR(j,start,i)
        {
            if(ret > sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y))))
            {
                ret = sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y)));
                if(ALL > ret)
                {
                    ALL = ret;
                    ANS1 = v[i];
                    ANS2 = v[j];
                }
            }
        }
    }
    return ret;
}

double Divide(int s,int e)
{
    if(s==e-1) return INF;
    int m = (s+e)/2;
    double d1 = Divide(s,m);
    double d2 = Divide(m,e);
    double d = min(d1,d2);
    return Conquer(s,e,d);
}

int main()
{
    sit[pii(1,1)] = 1;
    sit[pii(-1,1)] = 2;
    sit[pii(1,-1)] = 3;
    sit[pii(-1,-1)] = 4;
    input();
    Divide(0,n);
    pii a1 = pii(ANS1.x,ANS1.y);
    pii a2 = pii(ANS2.x,ANS2.y);
    int k = mp[a1].S;
    if(k==1) k = 4;
    else if(k==4) k = 1;
    else if(k==2) k = 3;
    else if(k==3) k = 2;
    fout << mp[a1].F << " " << k << " " << mp[a2].F << " " << mp[a2].S << endl;
    return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cstring>
#include <fstream>

using namespace std;

#define F first
#define PB(v,x) v.push_back(x)
#define size(X) (int)X.size()
#define S second
#define show(X) cerr << #X << " = " << X << endl;
#define getrandom(min,max) \
	((rand()%(int)(((max)+1)-(min)))+min)
#define foreach(var, container) \
	for(typeof((container).begin()) var = (container).begin(); \
			var != (container).end(); \
			++var)
#define SetBit(value, place) ((value) | (1 << (place)))
#define ClearBit(value, place) ((value) & (~(1 << (place))))
#define ToggleBit(value, place) ((value) ^ (1 << (place)))
#define GetBit(value, place) (((value) >> (place)) & 1)
#define GetPrecentage(Numerator, Denominator)	((Numerator)*100.0/(Denominator))
#define GI ({int t;scanf("%d",&t);t;})
#define GL ({LL t;scanf("%lld",&t);t;})
#define GD ({double t;scanf("%lf",&t);t;})
#define is istringstream
#define os ostringstream
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define REP(i,n) for (int i=0,_n=(n); i < _n; i++)
#define REV(i,n) for (int i=(n)-1; i >= 0; i--)
#define FOR(i,a,b) for (int _b=(b), i=(a); i < _b; i++)
#define ROR(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))
#define CLEAR(x) memset(x,0,sizeof x);
#define REVERSE(c) reverse(ALL(c))
#define UNIQUE(c) SORT(c),(c).resize(unique(ALL(c))-(c).begin())
#define INF 0x7fffffff
#define eps 1.0e-11
template <class X> void printa(X a,int n)
{
	REP(i,n) cerr << a[i] << " " ;
	cerr << endl;
}

template <class X> void printv(X v)
{
	foreach(it,v) cerr << *it << " " ;
	cerr << endl;
}
typedef pair<int,int> pii;
typedef long long ll;
typedef pair<ll,ll> pll;

ifstream fin("input.txt");
ofstream fout("output.txt");

const int MAXN = 60;
ll d[MAXN][MAXN];
ll c[MAXN][MAXN];
ll n,m;
ll A,B,C;

void input()
{
	fin >> n >> m;
	REP(i,n) REP(j,m)
		fin >> c[i][j];
	fin >> A >> B >> C;
}

void dynamic()
{
	d[0][0] = c[0][0];
	REP(i,n-1)
		d[i+1][0] = c[i+1][0]+d[i][0];
	REP(i,m-1)
		d[0][i+1] = c[0][i+1] + d[0][i];
	REP(i,n-1) REP(j,m-1)
		d[i+1][j+1] = d[i][j+1] + d[i+1][j] - d[i][j] + c[i+1][j+1];
}

bool check(ll x1,ll x2,ll x3)
{
	if(x1==A && x2 == B && x3 == C)
		return true;
	if(x1==A && x2 == C && x3 == B)
		return true;
	if(x1==B && x2 == A && x3 == C)
		return true;
	if(x1==B && x2 == C && x3 == A)
		return true;
	if(x1==C && x2 == A && x3 == B)
		return true;
	if(x1==C && x2 == B && x3 == A)
		return true;
	return false;
}

ll case1() // se khatte amoodi
{
	ll ret = 0;
	REP(i,m-1) FOR(j,i+1,m)
	{
		ll x1 = d[n-1][i];
		ll x2 = d[n-1][j]-d[n-1][i];
		ll x3 = d[n-1][m-1] - x1 - x2;
		if(check(x1,x2,x3))
			ret++;
	}
	return ret;
}

ll case2() // se khatte ofoghi
{
	ll ret = 0;
	REP(i,n-1) FOR(j,i+1,n)
	{
		ll x1 = d[i][m-1];
		ll x2 = d[j][m-1]-d[i][m-1];
		ll x3 = d[n-1][m-1] - x1 - x2;
		if(check(x1,x2,x3))
			ret++;
	}
	return ret;
}

int main()
{
	input();
	dynamic();
	ll sum = 0;
	sum+=case1();
	sum+=case2();
	int x1,x2,x3;
	x1= x2 = 0;
	x3 = d[n-1][m-1];
	if(check(x1,x2,x3))
		sum++;
	fout << sum << endl;
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cstring>
#include <fstream>

using namespace std;

#define F first
#define PB(v,x) v.push_back(x)
#define size(X) (int)X.size()
#define S second
#define show(X) cerr << #X << " = " << X << endl;
#define getrandom(min,max) \
	((rand()%(int)(((max)+1)-(min)))+min)
#define foreach(var, container) \
	for(typeof((container).begin()) var = (container).begin(); \
			var != (container).end(); \
			++var)
#define SetBit(value, place) ((value) | (1 << (place)))
#define ClearBit(value, place) ((value) & (~(1 << (place))))
#define ToggleBit(value, place) ((value) ^ (1 << (place)))
#define GetBit(value, place) (((value) >> (place)) & 1)
#define GetPrecentage(Numerator, Denominator)	((Numerator)*100.0/(Denominator))
#define GI ({int t;scanf("%d",&t);t;})
#define GL ({LL t;scanf("%lld",&t);t;})
#define GD ({double t;scanf("%lf",&t);t;})
#define is istringstream
#define os ostringstream
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define REP(i,n) for (int i=0,_n=(n); i < _n; i++)
#define REV(i,n) for (int i=(n)-1; i >= 0; i--)
#define FOR(i,a,b) for (int _b=(b), i=(a); i < _b; i++)
#define ROR(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))
#define CLEAR(x) memset(x,0,sizeof x);
#define REVERSE(c) reverse(ALL(c))
#define UNIQUE(c) SORT(c),(c).resize(unique(ALL(c))-(c).begin())
#define INF (int)1e9
#define eps 1.0e-11
#define PI(x) printf("%d ",x)
#define two(x) ((x)*(x))
template <class X> void printa(X a,int n)
{
	REP(i,n) cerr << a[i] << " " ;
	cerr << endl;
}

template <class X> void printv(X v)
{
	foreach(it,v) cerr << *it << " " ;
	cerr << endl;
}
typedef pair<int,int> pii;
typedef long long ll;
typedef pair<ll,ll> pll;
map<pii,pii> mp;
map<pii,int> sit;
ifstream fin("input.txt");
ofstream fout("output.txt");

struct point {
	int x,y;
	point(){;}
};

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

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

const int MAXN = (int)1e5 + 100;
point p[MAXN];
int n;
point ANS1,ANS2;

void input()
{
	fin >> n;
	REP(i,n)
	{
		fin >> p[i].x >> p[i].y;
		point l = p[i];
		if(l.x < 0) l.x *=-1;
		if(l.y < 0) l.y *=-1;
		if(mp.find(pii(l.x,l.y))!=mp.end())
		{
			fout << i << " " << sit[pii(p[i].x/l.x * -1,p[i].y/l.y * -1)] << " "<< mp[pii(l.x,l.y)].F << " " << mp[pii(l.x,l.y)].S << endl;
			exit(0);
		}
		int k1 = 1 , k2 = 1;
		if(l.x!=0) k1 = l.x / p[i].x;
		if(l.y != 0) k2 = l.y / p[i].y;
		mp[pii(l.x,l.y)] = pii(i+1,sit[pii(k1,k2)]);
		p[i] = l;
	}
	sort(p,p+n,cmp1);
}

double Conquer(int s,int e,double d)
{
	int m = (s+e)/2;
	double X = p[m].x;
	vector<point> v;
	FOR(i,s,e) if(abs((double)p[i].x - X) <= d) PB(v,p[i]);
	sort(v.begin(),v.end(),cmp2);
	REVERSE(v);
	int start = 0;
	double ret = d;
	REP(i,size(v))
	{
		while(abs(v[i].y - v[start].y) > d) start++;
		FOR(j,start,i)
		{
			if(ret > sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y))))
			{
				ret = sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y)));
				ANS1 = v[i];
				ANS2 = v[j];
			}
		}
	}
	return ret;
}

double Divide(int s,int e)
{
	if(s==e-1) return INF;
	int m = (s+e)/2;
	double d1 = Divide(s,m);
	double d2 = Divide(m,e);
	double d = min(d1,d2);
	return Conquer(s,e,d);
}

int main()
{
	sit[pii(1,1)] = 1;
	sit[pii(-1,1)] = 2;
	sit[pii(1,-1)] = 3;
	sit[pii(-1,-1)] = 4;
	input();
	Divide(0,n);
	pii a1 = pii(ANS1.x,ANS1.y);
	pii a2 = pii(ANS2.x,ANS2.y);
	int k = mp[a1].S;
	if(k==1) k = 4;
	else if(k==4) k = 1;
	else if(k==2) k = 3;
	else if(k==3) k = 2;
	fout << mp[a1].F << " " << k << " " << mp[a2].F << " " << mp[a2].S << endl;
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cstring>

using namespace std;

#define F first
#define PB(v,x) v.push_back(x)
#define size(X) (int)X.size()
#define S second
#define show(X) cerr << #X << " = " << X << endl;
#define getrandom(min,max) \
	((rand()%(int)(((max)+1)-(min)))+min)
#define foreach(var, container) \
	for(typeof((container).begin()) var = (container).begin(); \
			var != (container).end(); \
			++var)
#define SetBit(value, place) ((value) | (1 << (place)))
#define ClearBit(value, place) ((value) & (~(1 << (place))))
#define ToggleBit(value, place) ((value) ^ (1 << (place)))
#define GetBit(value, place) (((value) >> (place)) & 1)
#define GetPrecentage(Numerator, Denominator)	((Numerator)*100.0/(Denominator))
#define GI ({int t;scanf("%d",&t);t;})
#define GL ({LL t;scanf("%lld",&t);t;})
#define GD ({double t;scanf("%lf",&t);t;})
#define is istringstream
#define os ostringstream
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define REP(i,n) for (int i=0,_n=(n); i < _n; i++)
#define REV(i,n) for (int i=(n)-1; i >= 0; i--)
#define FOR(i,a,b) for (int _b=(b), i=(a); i < _b; i++)
#define ROR(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))
#define CLEAR(x) memset(x,0,sizeof x);
#define REVERSE(c) reverse(ALL(c))
#define UNIQUE(c) SORT(c),(c).resize(unique(ALL(c))-(c).begin())
#define INF (int)1e9
#define eps 1.0e-11
#define PI(x) printf("%d ",x)
#define two(x) ((x)*(x))
template <class X> void printa(X a,int n)
{
	REP(i,n) cerr << a[i] << " " ;
	cerr << endl;
}

template <class X> void printv(X v)
{
	foreach(it,v) cerr << *it << " " ;
	cerr << endl;
}
typedef pair<int,int> pii;
typedef long long ll;
typedef pair<ll,ll> pll;
map<pii,pii> mp;
map<pii,int> sit;

struct point {
	int x,y;
	point(){;}
	friend ostream &operator << (ostream &cout , point &a)
	{
		cout << a.x << " " << a.y;
		return cout;
	}
};

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

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

const int MAXN = (int)1e5 + 100;
point p[MAXN];
int n;
point ANS1,ANS2;

void input()
{
	n = GI;
	REP(i,n)
	{
		scanf("%d%d",&p[i].x, &p[i].y);
		point l = p[i];
		if(l.x < 0) l.x *=-1;
		if(l.y < 0) l.y *=-1;
		if(mp.find(pii(l.x,l.y))!=mp.end())
		{
			cout << i << " " << sit[pii(p[i].x/l.x * -1,p[i].y/l.y * -1)] << " "<< mp[pii(l.x,l.y)].F << " " << mp[pii(l.x,l.y)].S << endl;
			exit(0);
		}
		cerr << "!@#" << endl;
		int k1 = -1 , k2 = -1;
		if(l.x!=0) k1 = l.x / p[i].x;
		if(l.y != 0) k2 = l.y / p[i].y;
		mp[pii(l.x,l.y)] = pii(i+1,sit[pii(k1,k2)]);
		p[i] = l;
	}
	sort(p,p+n,cmp1);
}

double Conquer(int s,int e,double d)
{
	int m = (s+e)/2;
	double X = p[m].x;
	vector<point> v;
	FOR(i,s,e) if(abs((double)p[i].x - X) <= d) PB(v,p[i]);
	sort(v.begin(),v.end(),cmp2);
	REVERSE(v);
	int start = 0;
	double ret = d;
	REP(i,size(v))
	{
		while(abs(v[i].y - v[start].y) > d) start++;
		FOR(j,start,i)
		{
			if(ret > sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y))))
			{
				ret = sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y)));
				ANS1 = v[i];
				ANS2 = v[j];
			}
		}
	}
	return ret;
}

double Divide(int s,int e)
{
	if(s==e-1) return INF;
	int m = (s+e)/2;
	double d1 = Divide(s,m);
	double d2 = Divide(m,e);
	double d = min(d1,d2);
	return Conquer(s,e,d);
}

int main()
{
	sit[pii(1,1)] = 1;
	sit[pii(-1,1)] = 2;
	sit[pii(1,-1)] = 3;
	sit[pii(-1,-1)] = 4;
	input();
	Divide(0,n);
	pii a1 = pii(ANS1.x,ANS1.y);
	pii a2 = pii(ANS2.x,ANS2.y);
	int k = mp[a1].S;
	if(k==1) k = 4;
	if(k==4) k = 1;
	if(k==2) k = 3;
	if(k==3) k = 2;
	cout << mp[a1].F << " " << k << " " << mp[a2].F << " " << mp[a2].S << endl;
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cstring>
#include <fstream>

using namespace std;

#define F first
#define PB(v,x) v.push_back(x)
#define size(X) (int)X.size()
#define S second
#define show(X) cerr << #X << " = " << X << endl;
#define getrandom(min,max) \
	((rand()%(int)(((max)+1)-(min)))+min)
#define foreach(var, container) \
	for(typeof((container).begin()) var = (container).begin(); \
			var != (container).end(); \
			++var)
#define SetBit(value, place) ((value) | (1 << (place)))
#define ClearBit(value, place) ((value) & (~(1 << (place))))
#define ToggleBit(value, place) ((value) ^ (1 << (place)))
#define GetBit(value, place) (((value) >> (place)) & 1)
#define GetPrecentage(Numerator, Denominator)	((Numerator)*100.0/(Denominator))
#define GI ({int t;scanf("%d",&t);t;})
#define GL ({LL t;scanf("%lld",&t);t;})
#define GD ({double t;scanf("%lf",&t);t;})
#define is istringstream
#define os ostringstream
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define REP(i,n) for (int i=0,_n=(n); i < _n; i++)
#define REV(i,n) for (int i=(n)-1; i >= 0; i--)
#define FOR(i,a,b) for (int _b=(b), i=(a); i < _b; i++)
#define ROR(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))
#define CLEAR(x) memset(x,0,sizeof x);
#define REVERSE(c) reverse(ALL(c))
#define UNIQUE(c) SORT(c),(c).resize(unique(ALL(c))-(c).begin())
#define INF (int)1e9
#define eps 1.0e-11
#define PI(x) printf("%d ",x)
#define two(x) ((x)*(x))
template <class X> void printa(X a,int n)
{
	REP(i,n) cerr << a[i] << " " ;
	cerr << endl;
}

template <class X> void printv(X v)
{
	foreach(it,v) cerr << *it << " " ;
	cerr << endl;
}
typedef pair<int,int> pii;
typedef long long ll;
typedef pair<ll,ll> pll;
map<pii,pii> mp;
map<pii,int> sit;
ifstream fin("input.txt");
ofstream fout("output.txt");

struct point {
	int x,y;
	point(){;}
};

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

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

const int MAXN = (int)1e5 + 100;
point p[MAXN];
int n;
point ANS1,ANS2;
double ALL = INF;

void input()
{
	cin >> n;
	REP(i,n)
	{
		cin >> p[i].x >> p[i].y;
		point l = p[i];
		if(l.x < 0) l.x *=-1;
		if(l.y < 0) l.y *=-1;
		if(mp.find(pii(l.x,l.y))!=mp.end())
		{
			cout << i << " " << sit[pii(p[i].x/l.x * -1,p[i].y/l.y * -1)] << " "<< mp[pii(l.x,l.y)].F << " " << mp[pii(l.x,l.y)].S << endl;
			exit(0);
		}
		int k1 = 1 , k2 = 1;
		if(l.x!=0) k1 = l.x / p[i].x;
		if(l.y != 0) k2 = l.y / p[i].y;
		mp[pii(l.x,l.y)] = pii(i+1,sit[pii(k1,k2)]);
		p[i] = l;
	}
	sort(p,p+n,cmp1);
}

double Conquer(int s,int e,double d)
{
	int m = (s+e)/2;
	double X = p[m].x;
	vector<point> v;
	FOR(i,s,e) if(abs((double)p[i].x - X) <= d) PB(v,p[i]);
	sort(v.begin(),v.end(),cmp2);
	REVERSE(v);
	int start = 0;
	double ret = d;
	REP(i,size(v))
	{
		while(abs(v[i].y - v[start].y) > d) start++;
		FOR(j,start,i)
		{
			if(ret > sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y))))
			{
				ret = sqrt(two(abs(v[i].x-v[j].x)) + two(abs(v[i].y-v[j].y)));
				if(ALL > ret)
				{
					ALL = ret;
					ANS1 = v[i];
					ANS2 = v[j];
				}
			}
		}
	}
	return ret;
}

double Divide(int s,int e)
{
	if(s==e-1) return INF;
	int m = (s+e)/2;
	double d1 = Divide(s,m);
	double d2 = Divide(m,e);
	double d = min(d1,d2);
	return Conquer(s,e,d);
}

int main()
{
	sit[pii(1,1)] = 1;
	sit[pii(-1,1)] = 2;
	sit[pii(1,-1)] = 3;
	sit[pii(-1,-1)] = 4;
	input();
	Divide(0,n);
	pii a1 = pii(ANS1.x,ANS1.y);
	pii a2 = pii(ANS2.x,ANS2.y);
	int k = mp[a1].S;
	if(k==1) k = 4;
	else if(k==4) k = 1;
	else if(k==2) k = 3;
	else if(k==3) k = 2;
	cout << mp[a1].F << " " << k << " " << mp[a2].F << " " << mp[a2].S << endl;
	return 0;
}


#include <stdio.h>
#include <cmath>
#include <algorithm>
#define N 100000
#define INF 1e13
#define eps 1e-7

struct Point
{
    double x, y;
    int idx;
} arr[N+5], temp[N+5], que[N+5];
bool cmp1(Point arg1, Point arg2) { return arg1.x < arg2.x; }
bool cmp2(Point arg1, Point arg2) { return arg1.y < arg2.y; }
inline double dist(Point a, Point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); }
int chg[N+5];
double closestpair(int l, int r, int &a, int &b)
{
    double d, d1, d2, d3, ans;
    int i, j, k, m, idx1, idx2, fr, bk, a1, b1, a2, b2;

    if (r - l <= 1) return INF;
    //if (r - l == 2) {
	//		return dist(arr[l], arr[r-1]);
	//}
    /*if (r - l == 3)
    {
        d1 = dist(arr[l], arr[l+1]);
        d2 = dist(arr[l], arr[l+2]);
        d3 = dist(arr[l+1], arr[l+2]);
        return std::min(d1, std::min(d2, d3));
	}*/
	m = (l + r) / 2;

	d1 = closestpair(l, m, a1, b1);
	d2 = closestpair(m, r, a2, b2);

	d = std::min(d1, d2);
	if (d == d1) {
		a = a1;
		b = b1;
	}
	else {
		a = a2;
		b = b2;
	}
    idx1 = 0;
    for (i = l; i < m; i++)
        if (std::abs(arr[i].x - arr[m].x) <= d + eps)
            temp[idx1++] = arr[i];
    idx2 = idx1;
    for (i = m; i < r; i++)
        if (std::abs(arr[i].x - arr[m].x) <= d + eps)
            temp[idx2++] = arr[i];
    std::sort(temp, temp+idx1, cmp2);
    std::sort(temp+idx1, temp+idx2, cmp2);
    ans = d;
    /*j = idx1;
    for (i = 0; i < idx1; i++)
    {

    }*/
    fr = bk = 0;
    for (i = 0, j = idx1; i < idx1; i++)
    {
        while (j < idx2 && temp[j].y < temp[i].y + d + eps)
        {
            que[bk++] = temp[j];
            j++;
        }
        while (fr < bk && que[fr].y <= temp[i].y - d + eps)
            fr++;
        for(k = fr; k < bk; k++)
        {
            d1 = dist(que[k], temp[i]);
            if (d1 < ans + eps) {
					a = que[k].idx;
					b = temp[i].idx;
					ans = d1;
				}
        }
    }

    return ans;
}

int main()
{
    int n, i, a, b;
	 double d;
	 freopen("input.txt", "r", stdin);
	 freopen("output.txt", "w", stdout);
    scanf("%d", &n);
        for (i = 0; i < n; i++)
			{
            scanf("%lf %lf", &arr[i].x, &arr[i].y);
				arr[i].idx = i + 1;
				if (arr[i].x >= 0 && arr[i].y >= 0)
					chg[i] = 1;
				else if (arr[i].x < 0 && arr[i].y >= 0)
					chg[i] = 2;
				else if (arr[i].x >= 0 && arr[i].y < 0)
					chg[i] = 3;
				else
					chg[i] = 4;
				arr[i].x = fabs(arr[i].x);
				arr[i].y = fabs(arr[i].y);
			}
        std::sort(arr, arr+n, cmp1);
			d = closestpair(0, n, a, b);
        printf("%d %d %d %d\n", a, 5-chg[a-1], b, chg[b-1]);
    return 0;
}


#include <stdio.h>
#include <cmath>
#include <algorithm>
#define N 100000
#define INF 1e13
#define eps 1e-7

struct Point
{
    double x, y;
    int idx;
} arr[N+5], temp[N+5], que[N+5];
bool cmp1(Point arg1, Point arg2) { return arg1.x < arg2.x; }
bool cmp2(Point arg1, Point arg2) { return arg1.y < arg2.y; }
inline double dist(Point a, Point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); }
int chg[N+5];
double closestpair(int l, int r, int &a, int &b)
{
    double d, d1, d2, d3, ans;
    int i, j, k, m, idx1, idx2, fr, bk, a1, b1, a2, b2;

    if (r - l <= 1) return INF;
    //if (r - l == 2) {
			return dist(arr[l], arr[r-1]);
	//}
    /*if (r - l == 3)
    {
        d1 = dist(arr[l], arr[l+1]);
        d2 = dist(arr[l], arr[l+2]);
        d3 = dist(arr[l+1], arr[l+2]);
        return std::min(d1, std::min(d2, d3));
	}*/
	m = (l + r) / 2;

	d1 = closestpair(l, m, a1, b1);
	d2 = closestpair(m, r, a2, b2);

	d = std::min(d1, d2);
	if (d == d1) {
		a = a1;
		b = b1;
	}
	else {
		a = a2;
		b = b2;
	}
    idx1 = 0;
    for (i = l; i < m; i++)
        if (std::abs(arr[i].x - arr[m].x) <= d + eps)
            temp[idx1++] = arr[i];
    idx2 = idx1;
    for (i = m; i < r; i++)
        if (std::abs(arr[i].x - arr[m].x) <= d + eps)
            temp[idx2++] = arr[i];
    std::sort(temp, temp+idx1, cmp2);
    std::sort(temp+idx1, temp+idx2, cmp2);
    ans = d;
    /*j = idx1;
    for (i = 0; i < idx1; i++)
    {

    }*/
    fr = bk = 0;
    for (i = 0, j = idx1; i < idx1; i++)
    {
        while (j < idx2 && temp[j].y < temp[i].y + d + eps)
        {
            que[bk++] = temp[j];
            j++;
        }
        while (fr < bk && que[fr].y <= temp[i].y - d + eps)
            fr++;
        for(k = fr; k < bk; k++)
        {
            d1 = dist(que[k], temp[i]);
            if (d1 < ans + eps) {
					a = que[k].idx;
					b = temp[i].idx;
					ans = d1;
				}
        }
    }

    return ans;
}

int main()
{
    int n, i, a, b;
	 double d;
	 freopen("input.txt", "r", stdin);
	 freopen("output.txt", "w", stdout);
    scanf("%d", &n);
        for (i = 0; i < n; i++)
			{
            scanf("%lf %lf", &arr[i].x, &arr[i].y);
				arr[i].idx = i + 1;
				if (arr[i].x >= 0 && arr[i].y >= 0)
					chg[i] = 1;
				else if (arr[i].x < 0 && arr[i].y >= 0)
					chg[i] = 2;
				else if (arr[i].x >= 0 && arr[i].y < 0)
					chg[i] = 3;
				else
					chg[i] = 4;
				arr[i].x = fabs(arr[i].x);
				arr[i].y = fabs(arr[i].y);
			}
        std::sort(arr, arr+n, cmp1);
			d = closestpair(0, n, arr, a, b);
        printf("%d %d %d %d\n", a, 5-chg[a-1], b, chg[b-1]);
    return 0;
}


#include <stdio.h>
#include <cmath>
#include <algorithm>
#define N 50000
#define INF 610000000.0
#define eps 10e-9

struct Point
{
    double x, y;
    int idx;
} temp[N+5], que[N+5];
bool cmp1(Point arg1, Point arg2) { return arg1.x < arg2.x; }
bool cmp2(Point arg1, Point arg2) { return arg1.y < arg2.y; }
inline double dist(Point a, Point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); }
int chg[N+5];
double closestpair(int l, int r, Point arr[], int &a, int &b)
{
    //Point temp[N+5];
    double d, d1, d2, d3, ans;
    int i, j, k, m, idx1, idx2, fr, bk, a1, b1, a2, b2;

    if (r - l <= 1) return INF;
    //if (r - l == 2) {
	//		return dist(arr[l], arr[r-1]);
	//}
    /*if (r - l == 3)
    {
        d1 = dist(arr[l], arr[l+1]);
        d2 = dist(arr[l], arr[l+2]);
        d3 = dist(arr[l+1], arr[l+2]);
        return std::min(d1, std::min(d2, d3));
    }*/
    m = (l + r) / 2;

    d1 = closestpair(l, m, arr, a1, b1);
    d2 = closestpair(m, r, arr, a2, b2);

    d = std::min(d1, d2);
	 if (d == d1) {
		a = a1;
		b = b1;
	 }
	else {
		a = a2;
		b = b2;
	}
    idx1 = 0;
    for (i = l; i < m; i++)
        if (std::abs(arr[i].x - arr[m].x) <= d + eps)
            temp[idx1++] = arr[i];
    idx2 = idx1;
    for (i = m; i < r; i++)
        if (std::abs(arr[i].x - arr[m].x) <= d + eps)
            temp[idx2++] = arr[i];
    std::sort(temp, temp+idx1, cmp2);
    std::sort(temp+idx1, temp+idx2, cmp2);
    ans = d;
    /*j = idx1;
    for (i = 0; i < idx1; i++)
    {

    }*/
    fr = bk = 0;
    for (i = 0, j = idx1; i < idx1; i++)
    {
        while (j < idx2 && temp[j].y < temp[i].y + d + eps)
        {
            que[bk++] = temp[j];
            j++;
        }
        while (fr < bk && que[fr].y <= temp[i].y - d + eps)
            fr++;
        for(k = fr; k < bk; k++)
        {
            d1 = dist(que[k], temp[i]);
            if (d1 < ans + eps) {
					a = que[k].idx;
					b = temp[i].idx;
					ans = d1;
				}
        }
    }

    return ans;
}

int main()
{
    Point arr[N+5];
    int n, i, a, b;
	 double d;
	 freopen("input.txt", "r", stdin);
	 freopen("output.txt", "w", stdout);
    scanf("%d", &n);
        for (i = 0; i < n; i++)
			{
            scanf("%lf %lf", &arr[i].x, &arr[i].y);
				arr[i].idx = i + 1;
				if (arr[i].x >= 0 && arr[i].y >= 0)
					chg[i] = 1;
				else if (arr[i].x < 0 && arr[i].y >= 0)
					chg[i] = 2;
				else if (arr[i].x >= 0 && arr[i].y < 0)
					chg[i] = 3;
				else
					chg[i] = 4;
				arr[i].x = fabs(arr[i].x);
				arr[i].y = fabs(arr[i].y);
			}
        std::sort(arr, arr+n, cmp1);
			d = closestpair(0, n, arr, a, b);
        printf("%d %d %d %d\n", a, 5-chg[a-1], b, chg[b-1]);
    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
struct dot
{
    int x,y,num;
};
dot all[100001],mer[100001];
int p[100001],pi,pj,mini,nx[100001];
int dis(dot a,dot b)
{
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
bool cmp(dot a,dot b)
{
    return a.x==b.x?a.y<b.y:a.x<b.x;
}
bool cmp2(dot a,dot b)
{
    return a.y<b.y;
}
void find(int l,int r)
{
    if(r-l==2)
    {
        int dis1 = dis(all[l],all[l+1]),
            dis2 = dis(all[l+1],all[r]),
            dis3 = dis(all[l],all[r]);
        if(dis1 <= dis2 && dis1 <= dis3 && mini>dis1)
        {
            mini=dis1;
            pi=all[l].num;pj=all[l+1].num;
        }
        else if(dis2 <= dis1 && dis2 <= dis3 && mini>dis2)
        {
            mini=dis2;
            pi=all[l+1].num;pj=all[r].num;
        }
        else if(dis3 <= dis2 && dis3 <= dis1 && mini>dis3)
        {
            mini=dis3;
            pi=all[l].num;pj=all[r].num;
        }
        return;
    }
    else if(r-l==1)
    {
        int dis1=dis(all[r],all[l]);
        if(dis1<mini)
        {
            pi=all[l].num;
            pj=all[r].num;
            mini=dis1;
        }
    }
    else
    {
        int mc=0;
        int mid = (r+l)/2,midx=(nx[mid]+nx[mid+1])/2;
        find(l,mid);find(mid+1,r);
        for(int i=l;i<=mid;i++)
        {
            if(midx - all[i].x >=0)
                mer[mc++]=all[i];
        }
        for(int i=mid+1;i<=r;i++)
        {
            if(all[i].x-midx >=0)
                mer[mc++]=all[i];
        }
        sort(mer,mer+mc,cmp2);
        for(int i=0;i<mc;i++)
        {
            if(i>=2 && dis(mer[i],mer[i-2]) < mini)
            {
                mini = dis(mer[i],mer[i-2]);
                pi=all[i-2].num;pj=all[i].num;
            }
            else if(i>=1 && dis(mer[i],mer[i-1]) < mini)
            {
                mini = dis(mer[i],mer[i-1]);
                pi=all[i-1].num;pj=all[i].num;
            }
            else if(i<mc-1 && dis(mer[i],mer[i+1]) < mini)
            {
                mini = dis(mer[i],mer[i+1]);
                pi=all[i].num;pj=all[i+1].num;
            }
            else if(i<mc-2 && dis(mer[i],mer[i+2]) < mini)
            {
                mini = dis(mer[i],mer[i+2]);
                pi=all[i].num;pj=all[i+2].num;
            }
        }
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        mini=2147483647;
        for(int i=0;i<n;i++)
        {
            scanf("%d %d",&all[i].x,&all[i].y);
            all[i].num=i;
            nx[i]=all[i].x;
            if(all[i].x>=0 && all[i].y>=0)
                p[i]=1;
            else if(all[i].x<0 && all[i].y>=0)
            {
                p[i]=2;
                all[i].x*=-1;
            }
            else if(all[i].x>=0 && all[i].y<0)
            {
                p[i]=3;
                all[i].y*=-1;
            }
            else if(all[i].x<0 && all[i].y<0)
            {
                p[i]=4;
                all[i].x*=-1;all[i].y*=-1;
            }
        }
        sort(all,all+n,cmp);
        find(0,n-1);
        printf("%d %d %d %d\n",pi+1,p[pi],pj+1,5-p[pj]);
    }
}


#include <stdio.h>
#include <cmath>
#include <algorithm>
#define N 100000
#define INF 1e13
#define eps 1e-7

struct Point
{
    double x, y;
    int idx;
} arr[N+5], temp[N+5], que[N+5];
bool cmp1(Point arg1, Point arg2) { return arg1.x < arg2.x; }
bool cmp2(Point arg1, Point arg2) { return arg1.y < arg2.y; }
inline double dist(Point a, Point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); }
int chg[N+5];
double closestpair(int l, int r, int &a, int &b)
{
    double d, d1, d2, d3, ans;
    int i, j, k, m, idx1, idx2, fr, bk, a1, b1, a2, b2;

    if (r - l <= 1) return INF;
    //if (r - l == 2) {
			return dist(arr[l], arr[r-1]);
	//}
    /*if (r - l == 3)
    {
        d1 = dist(arr[l], arr[l+1]);
        d2 = dist(arr[l], arr[l+2]);
        d3 = dist(arr[l+1], arr[l+2]);
        return std::min(d1, std::min(d2, d3));
	}*/
	m = (l + r) / 2;

	d1 = closestpair(l, m, a1, b1);
	d2 = closestpair(m, r, a2, b2);

	d = std::min(d1, d2);
	if (d == d1) {
		a = a1;
		b = b1;
	}
	else {
		a = a2;
		b = b2;
	}
    idx1 = 0;
    for (i = l; i < m; i++)
        if (std::abs(arr[i].x - arr[m].x) <= d + eps)
            temp[idx1++] = arr[i];
    idx2 = idx1;
    for (i = m; i < r; i++)
        if (std::abs(arr[i].x - arr[m].x) <= d + eps)
            temp[idx2++] = arr[i];
    std::sort(temp, temp+idx1, cmp2);
    std::sort(temp+idx1, temp+idx2, cmp2);
    ans = d;
    /*j = idx1;
    for (i = 0; i < idx1; i++)
    {

    }*/
    fr = bk = 0;
    for (i = 0, j = idx1; i < idx1; i++)
    {
        while (j < idx2 && temp[j].y < temp[i].y + d + eps)
        {
            que[bk++] = temp[j];
            j++;
        }
        while (fr < bk && que[fr].y <= temp[i].y - d + eps)
            fr++;
        for(k = fr; k < bk; k++)
        {
            d1 = dist(que[k], temp[i]);
            if (d1 < ans + eps) {
					a = que[k].idx;
					b = temp[i].idx;
					ans = d1;
				}
        }
    }

    return ans;
}

int main()
{
    int n, i, a, b;
	 double d;
	 freopen("input.txt", "r", stdin);
	 freopen("output.txt", "w", stdout);
    scanf("%d", &n);
        for (i = 0; i < n; i++)
			{
            scanf("%lf %lf", &arr[i].x, &arr[i].y);
				arr[i].idx = i + 1;
				if (arr[i].x >= 0 && arr[i].y >= 0)
					chg[i] = 1;
				else if (arr[i].x < 0 && arr[i].y >= 0)
					chg[i] = 2;
				else if (arr[i].x >= 0 && arr[i].y < 0)
					chg[i] = 3;
				else
					chg[i] = 4;
				arr[i].x = fabs(arr[i].x);
				arr[i].y = fabs(arr[i].y);
			}
        std::sort(arr, arr+n, cmp1);
			d = closestpair(0, n, a, b);
        printf("%d %d %d %d\n", a, 5-chg[a-1], b, chg[b-1]);
    return 0;
}


#include <cstdio>
#include <math.h>
#include <algorithm>

typedef struct {
	int x;
	int y;
	int index;
}Point;

Point points[100005];

int centerCluster[100005];
int comparePointsX(const void *indexA, const void *indexB) {
	return abs(points[*((int*)indexA)].x) - abs(points[*((int*)indexB)].x);
}
int comparePointsY(const void *indexA, const void *indexB) {
	return abs(points[*((int*)indexA)].y) - abs(points[*((int*)indexB)].y);
}
int pointsXIndex[100005], pointsYIndex[100005];

int bestA, bestB, bestDis;
void minDis(int l, int r) {
	int dis, tmp;
	int a, b;
	dis = 10000000;
	if (r - l == 2) {
		tmp = pow(abs(points[pointsXIndex[l]].x) - abs(points[pointsXIndex[l + 1]].x), 2);
		tmp += pow(abs(points[pointsXIndex[l]].y) - abs(points[pointsXIndex[l + 1]].y), 2);
		if (tmp < bestDis) {
			bestDis = tmp;
			bestA = pointsXIndex[l];
			bestB = pointsXIndex[l + 1];
		}

		tmp = pow(abs(points[pointsXIndex[l]].x) - abs(points[pointsXIndex[l + 2]].x), 2);
		tmp += pow(abs(points[pointsXIndex[l]].y) - abs(points[pointsXIndex[l + 2]].y), 2);
		if (tmp < bestDis) {
			bestDis = tmp;
			bestA = pointsXIndex[l];
			bestB = pointsXIndex[l + 2];
		}

		tmp = pow(abs(points[pointsXIndex[l + 2]].x) - abs(points[pointsXIndex[l + 1]].x), 2);
		tmp += pow(abs(points[pointsXIndex[l + 2]].y) - abs(points[pointsXIndex[l + 1]].y), 2);
		if (tmp < bestDis) {
			bestDis = tmp;
			bestA = pointsXIndex[l + 1];
			bestB = pointsXIndex[l + 2];
		}

		return;
	}
	if (r - l == 1) {
		tmp = pow(abs(points[pointsXIndex[l]].x) - abs(points[pointsXIndex[l + 1]].x), 2);
		tmp += pow(abs(points[pointsXIndex[l]].y) - abs(points[pointsXIndex[l + 1]].y), 2);
		if (tmp < bestDis) {
			bestDis = tmp;
			bestA = pointsXIndex[l];
			bestB = pointsXIndex[l + 1];
		}
		return;
	}

	int centerIndex = (r + l) / 2;
	minDis(l, centerIndex);
	minDis(centerIndex + 1, r);
	int i, j;
	int centerX = abs(points[pointsXIndex[centerIndex]].x);
	int centerClusterCnt = 0;
	for (i = l; i <= r; i++) {
		if ((abs(abs(points[pointsXIndex[i]].x) - centerX)) <= pow(bestDis, 0.5) + 0.0001) {
			centerCluster[centerClusterCnt] = i;
			centerClusterCnt++;
		}
	}

	qsort(centerCluster, centerClusterCnt, sizeof(centerCluster[0]), comparePointsY);

	for (i = 0; i < centerClusterCnt; i++) {
		for (j = 1; j + i <  centerClusterCnt && j < 8; j++) {
			tmp = pow(abs(points[centerCluster[i]].x) - abs(points[centerCluster[i + j]].x), 2);
			tmp += pow(abs(points[centerCluster[i]].y) - abs(points[centerCluster[i + j]].y), 2);
			if (tmp < bestDis) {
				bestDis = tmp;
				bestA = centerCluster[i];
				bestB = centerCluster[i + j];
			}
		}
	}

}
int main(){
	int n, i;
	bestDis = 10000000;

	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	scanf("%d", &n);
	for (i = 0; i < n; i++) {
		pointsXIndex[i] = i;
		pointsYIndex[i] = i;
		points[i].index = i;
		scanf("%d", &(points[i].x));
		scanf("%d", &(points[i].y));
	}

	qsort(pointsXIndex, n, sizeof(pointsYIndex[0]), comparePointsX);
	qsort(pointsYIndex, n, sizeof(pointsXIndex[0]), comparePointsY);

	minDis(0, n - 1);
	//printf("%d\n", bestDis);
	if (points[bestA].x * points[bestB].x > 0)
		if (points[bestA].y * points[bestB].y > 0)
			printf("%d %d %d %d", bestA + 1, 1, bestB + 1, 4);
		else
			printf("%d %d %d %d", bestA + 1, 1, bestB + 1, 2);
	else
		if (points[bestA].y * points[bestB].y > 0)
			printf("%d %d %d %d", bestA + 1, 1, bestB + 1, 3);
		else
			printf("%d %d %d %d", bestA + 1, 1, bestB + 1, 1);

	return 0;
}


#include <cstdio>
#include <math.h>
#include <algorithm>

typedef struct {
	int x;
	int y;
	int index;
}Point;

Point points[100005];

int centerCluster[100005];
int comparePointsX(const void *indexA, const void *indexB) {
	return abs(points[*((int*)indexA)].x) - abs(points[*((int*)indexB)].x);
}
int comparePointsY(const void *indexA, const void *indexB) {
	return abs(points[*((int*)indexA)].y) - abs(points[*((int*)indexB)].y);
}
int pointsXIndex[100005], pointsYIndex[100005];

int bestA, bestB, bestDis;
void minDis(int l, int r) {
	int dis, tmp;
	int a, b;
	dis = 10000000;
	if (r - l <= 2) {
		tmp = pow(abs(points[pointsXIndex[l]].x) - abs(points[pointsXIndex[l + 1]].x), 2);
		tmp += pow(abs(points[pointsXIndex[l]].y) - abs(points[pointsXIndex[l + 1]].y), 2);
		if (tmp < bestDis) {
			bestDis = tmp;
			bestA = pointsXIndex[l];
			bestB = pointsXIndex[l + 1];
		}

		tmp = pow(abs(points[pointsXIndex[l]].x) - abs(points[pointsXIndex[l + 2]].x), 2);
		tmp += pow(abs(points[pointsXIndex[l]].y) - abs(points[pointsXIndex[l + 2]].y), 2);
		if (tmp < bestDis) {
			bestDis = tmp;
			bestA = pointsXIndex[l];
			bestB = pointsXIndex[l + 2];
		}

		tmp = pow(abs(points[pointsXIndex[l + 2]].x) - abs(points[pointsXIndex[l + 1]].x), 2);
		tmp += pow(abs(points[pointsXIndex[l + 2]].y) - abs(points[pointsXIndex[l + 1]].y), 2);
		if (tmp < bestDis) {
			bestDis = tmp;
			bestA = pointsXIndex[l + 1];
			bestB = pointsXIndex[l + 2];
		}

		return;
	}

	int centerIndex = (r + l) / 2;
	minDis(l, centerIndex);
	minDis(centerIndex + 1, r);
	int i, j;
	int centerX = points[pointsXIndex[centerIndex]].x;
	int centerClusterCnt = 0;
	for (i = l; i <= r; i++) {
		if ((abs(points[pointsXIndex[i]].x - points[pointsXIndex[centerIndex]].x)) <= pow(bestDis, 0.5) + 0.0001) {
			centerCluster[centerClusterCnt] = i;
			centerClusterCnt++;
		}
	}

	qsort(centerCluster, centerClusterCnt, sizeof(centerCluster[0]), comparePointsY);

	for (i = 0; i < centerClusterCnt; i++) {
		for (j = 1; j + i <  centerClusterCnt && j < 8; j++) {
			tmp = pow(abs(points[centerCluster[i]].x) - abs(points[centerCluster[i + j]].x), 2);
			tmp += pow(abs(points[centerCluster[i]].y) - abs(points[centerCluster[i + j]].y), 2);
			if (tmp < bestDis) {
				bestDis = tmp;
				bestA = centerCluster[i];
				bestB = centerCluster[j];
			}
		}
	}

}
int main(){
	int n, i;
	bestDis = 10000000;

	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	scanf("%d", &n);
	for (i = 0; i < n; i++) {
		pointsXIndex[i] = i;
		pointsYIndex[i] = i;
		points[i].index = i;
		scanf("%d", &(points[i].x));
		scanf("%d", &(points[i].y));
	}

	qsort(pointsXIndex, n, sizeof(pointsYIndex[0]), comparePointsX);
	qsort(pointsYIndex, n, sizeof(pointsXIndex[0]), comparePointsY);

	minDis(0, n - 1);
//	printf("%d\n", bestDis);
	if (points[bestA].x * points[bestB].x > 0)
		if (points[bestA].y * points[bestB].y > 0)
			printf("%d %d %d %d", bestA + 1, 1, bestB + 1, 4);
		else
			printf("%d %d %d %d", bestA + 1, 1, bestB + 1, 2);
	else
		if (points[bestA].y * points[bestB].y > 0)
			printf("%d %d %d %d", bestA + 1, 1, bestB + 1, 3);
		else
			printf("%d %d %d %d", bestA + 1, 1, bestB + 1, 1);

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define MAX_N 1000010

int N, M;
double a[MAX_N], b[MAX_N], c[MAX_N], d[MAX_N];
double x[MAX_N], cc[MAX_N], dd[MAX_N];
/*

( b0 c0  0  0 a0 | d0 )
( a1 b1 c1  0  0 | d1 )
( 0  a2 b2 c2  0 | d2 )
( 0   0 a3 b3 c3 | d3 )
( c4  0  0 a4 b4 | d4 )

ATENCAO : o sistema soh eh trigonal se a0 = c4 = 0, entao pra funcionar
os vetores de entrada tem q satisfazer isso. Alem disso se o sistema nao tiver
exatamente uma solucao o algoritmo nao funciona.

*/

double solve_trigonal(int n){
	//Assume que o sistema tem solução (i.e. Det != 0)
	cc[0] = c[0]/b[0];
	for(int i=1; i<n; i++){
		cc[i] = c[i]/(b[i]-a[i]*cc[i-1]);
	}

	dd[0] = d[0]/b[0];
	for(int i=1; i<n; i++){
		dd[i] = (d[i] - a[i]*dd[i-1])/(b[i] - a[i]*cc[i-1]);
	}

	x[n-1] = dd[n-1];
	for(int i=n-2; i>=0; i--){
		x[i] = dd[i] - cc[i]*x[i+1];
	}
}

double q[MAX_N];

int main(){
	int R, C;
	while(scanf("%d %d", &N, &M)!=EOF){
		scanf("%d %d", &R, &C);
		R--; C--;

		if(M==1){
			printf("%.6lf\n", (1.0*N)/2.0);
		}

		for(int i=0; i<M; i++){
			a[i] = -0.25;
			b[i] = 3.0/4.0;
			c[i] = -0.25;
			q[i] = 0.0;
		}
		a[0] = 0.0;
		a[M-1] = -1.0/3.0;
		b[0] = 2.0/3.0;
		b[M-1] = 2.0/3.0;
		c[0] = -1.0/3.0;
		c[M-1] = 0.0;

		for(int i=N-2; i>=R; i--){
			for(int j=0; j<M; j++){
				if((j==0) || (j==(M-1))){
					d[j] = 1.0 + (1.0*q[j])/3.0;
				}
				else{
					d[j] = 1.0 + (1.0*q[j])/4.0;
				}
			}
			solve_trigonal(M);
			for(int j=0; j<M; j++){
				q[j] = x[j];
			}
		}

		printf("%.6lf\n", x[C]);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define MAX_N 1000010

int N, M;
double a[MAX_N], b[MAX_N], c[MAX_N], d[MAX_N];
double x[MAX_N], cc[MAX_N], dd[MAX_N];
/*

( b0 c0  0  0 a0 | d0 )
( a1 b1 c1  0  0 | d1 )
( 0  a2 b2 c2  0 | d2 )
( 0   0 a3 b3 c3 | d3 )
( c4  0  0 a4 b4 | d4 )

ATENCAO : o sistema soh eh trigonal se a0 = c4 = 0, entao pra funcionar
os vetores de entrada tem q satisfazer isso. Alem disso se o sistema nao tiver
exatamente uma solucao o algoritmo nao funciona.

*/

double solve_trigonal(int n){
	//Assume que o sistema tem solução (i.e. Det != 0)
	cc[0] = c[0]/b[0];
	for(int i=1; i<n; i++){
		cc[i] = c[i]/(b[i]-a[i]*cc[i-1]);
	}

	dd[0] = d[0]/b[0];
	for(int i=1; i<n; i++){
		dd[i] = (d[i] - a[i]*dd[i-1])/(b[i] - a[i]*cc[i-1]);
	}

	x[n-1] = dd[n-1];
	for(int i=n-2; i>=0; i--){
		x[i] = dd[i] - cc[i]*x[i+1];
	}
}

double q[MAX_N];

int main(){
	int R, C;
	while(scanf("%d %d", &N, &M)!=EOF){
		scanf("%d %d", &R, &C);
		R--; C--;

		if(M==1){
			printf("%.6lf\n", (2.0*(N-1.0)));
		}

		for(int i=0; i<M; i++){
			a[i] = -0.25;
			b[i] = 3.0/4.0;
			c[i] = -0.25;
			q[i] = 0.0;
		}
		a[0] = 0.0;
		a[M-1] = -1.0/3.0;
		b[0] = 2.0/3.0;
		b[M-1] = 2.0/3.0;
		c[0] = -1.0/3.0;
		c[M-1] = 0.0;

		for(int i=N-2; i>=R; i--){
			for(int j=0; j<M; j++){
				if((j==0) || (j==(M-1))){
					d[j] = 1.0 + (1.0*q[j])/3.0;
				}
				else{
					d[j] = 1.0 + (1.0*q[j])/4.0;
				}
			}
			solve_trigonal(M);
			for(int j=0; j<M; j++){
				q[j] = x[j];
			}
		}

		printf("%.6lf\n", x[C]);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define MAX_N 1000010

int N, M;
double a[MAX_N], b[MAX_N], c[MAX_N], d[MAX_N];
double x[MAX_N], cc[MAX_N], dd[MAX_N];
/*

( b0 c0  0  0 a0 | d0 )
( a1 b1 c1  0  0 | d1 )
( 0  a2 b2 c2  0 | d2 )
( 0   0 a3 b3 c3 | d3 )
( c4  0  0 a4 b4 | d4 )

ATENCAO : o sistema soh eh trigonal se a0 = c4 = 0, entao pra funcionar
os vetores de entrada tem q satisfazer isso. Alem disso se o sistema nao tiver
exatamente uma solucao o algoritmo nao funciona.

*/

double solve_trigonal(int n){
	//Assume que o sistema tem solução (i.e. Det != 0)
	cc[0] = c[0]/b[0];
	for(int i=1; i<n; i++){
		cc[i] = c[i]/(b[i]-a[i]*cc[i-1]);
	}

	dd[0] = d[0]/b[0];
	for(int i=1; i<n; i++){
		dd[i] = (d[i] - a[i]*dd[i-1])/(b[i] - a[i]*cc[i-1]);
	}

	x[n-1] = dd[n-1];
	for(int i=n-2; i>=0; i--){
		x[i] = dd[i] - cc[i]*x[i+1];
	}
}

double q[MAX_N];

int main(){
	int R, C;
	while(scanf("%d %d", &N, &M)!=EOF){
		scanf("%d %d", &R, &C);
		R--; C--;

		if(M==1){
			printf("%.10lf\n", 2.0*(N-R-1.0));
			continue;
		}

		for(int i=0; i<M; i++){
			a[i] = -0.25;
			b[i] = 3.0/4.0;
			c[i] = -0.25;
			q[i] = 0.0;
		}
		a[0] = 0.0;
		a[M-1] = -1.0/3.0;
		b[0] = 2.0/3.0;
		b[M-1] = 2.0/3.0;
		c[0] = -1.0/3.0;
		c[M-1] = 0.0;

		for(int i=N-2; i>=R; i--){
			for(int j=0; j<M; j++){
				if((j==0) || (j==(M-1))){
					d[j] = 1.0 + (1.0*q[j])/3.0;
				}
				else{
					d[j] = 1.0 + (1.0*q[j])/4.0;
				}
			}
			solve_trigonal(M);
			for(int j=0; j<M; j++){
				q[j] = x[j];
			}
		}

		printf("%.10lf\n", x[C]);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define MAX_N 1000010

int N, M;
double a[MAX_N], b[MAX_N], c[MAX_N], d[MAX_N];
double x[MAX_N], cc[MAX_N], dd[MAX_N];
/*

( b0 c0  0  0 a0 | d0 )
( a1 b1 c1  0  0 | d1 )
( 0  a2 b2 c2  0 | d2 )
( 0   0 a3 b3 c3 | d3 )
( c4  0  0 a4 b4 | d4 )

ATENCAO : o sistema soh eh trigonal se a0 = c4 = 0, entao pra funcionar
os vetores de entrada tem q satisfazer isso. Alem disso se o sistema nao tiver
exatamente uma solucao o algoritmo nao funciona.

*/

double solve_trigonal(int n){
	//Assume que o sistema tem solução (i.e. Det != 0)
	cc[0] = c[0]/b[0];
	for(int i=1; i<n; i++){
		cc[i] = c[i]/(b[i]-a[i]*cc[i-1]);
	}

	dd[0] = d[0]/b[0];
	for(int i=1; i<n; i++){
		dd[i] = (d[i] - a[i]*dd[i-1])/(b[i] - a[i]*cc[i-1]);
	}

	x[n-1] = dd[n-1];
	for(int i=n-2; i>=0; i--){
		x[i] = dd[i] - cc[i]*x[i+1];
	}
}

double q[MAX_N];

int main(){
	int R, C;
	while(scanf("%d %d", &N, &M)!=EOF){
		scanf("%d %d", &R, &C);
		R--; C--;

		if(M==1){
			printf("%.6lf\n", (2.0*(N-1.0)));
			continue;
		}

		for(int i=0; i<M; i++){
			a[i] = -0.25;
			b[i] = 3.0/4.0;
			c[i] = -0.25;
			q[i] = 0.0;
		}
		a[0] = 0.0;
		a[M-1] = -1.0/3.0;
		b[0] = 2.0/3.0;
		b[M-1] = 2.0/3.0;
		c[0] = -1.0/3.0;
		c[M-1] = 0.0;

		for(int i=N-2; i>=R; i--){
			for(int j=0; j<M; j++){
				if((j==0) || (j==(M-1))){
					d[j] = 1.0 + (1.0*q[j])/3.0;
				}
				else{
					d[j] = 1.0 + (1.0*q[j])/4.0;
				}
			}
			solve_trigonal(M);
			for(int j=0; j<M; j++){
				q[j] = x[j];
			}
		}

		printf("%.6lf\n", x[C]);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define MAX 1010
#define IT_MAX 100

double A[MAX], B[MAX], C[MAX];

int main(){
	int r, c, N, M;
	while(scanf("%d %d", &N, &M)!=EOF){
		scanf("%d %d", &r, &c);
		r--; c--;

		memset(A, 0.0, sizeof(A));
		for(int i=N-2; i>=r; i--){
			memset(B, 0.0, sizeof(B));
			memset(C, 0.0, sizeof(C));
			for(int it=0; it<IT_MAX; it++){
				for(int j=0; j<M; j++){
					double termos = 1.0;
					double sum = A[j];
					for(int k=-1; k<=1; k++){
						if((k+j)>=0 && (k+j)<M){
							termos++;
							sum += B[k+j];
						}
					}
					C[j] = 1.0 + (sum)/termos;
				}
				for(int j=0; j<M; j++){
					B[j] = C[j];
				}
			}
			//A <- B
			for(int j=0; j<M; j++){
				A[j] = B[j];
			}
		}

		printf("%.10lf\n", A[c]);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define MAX_N 1000010

int N, M;
double a[MAX_N], b[MAX_N], c[MAX_N], d[MAX_N];
double x[MAX_N], cc[MAX_N], dd[MAX_N];
/*

( b0 c0  0  0 a0 | d0 )
( a1 b1 c1  0  0 | d1 )
( 0  a2 b2 c2  0 | d2 )
( 0   0 a3 b3 c3 | d3 )
( c4  0  0 a4 b4 | d4 )

ATENCAO : o sistema soh eh trigonal se a0 = c4 = 0, entao pra funcionar
os vetores de entrada tem q satisfazer isso. Alem disso se o sistema nao tiver
exatamente uma solucao o algoritmo nao funciona.

*/

double solve_trigonal(int n){
	//Assume que o sistema tem solução (i.e. Det != 0)
	cc[0] = c[0]/b[0];
	for(int i=1; i<n; i++){
		cc[i] = c[i]/(b[i]-a[i]*cc[i-1]);
	}

	dd[0] = d[0]/b[0];
	for(int i=1; i<n; i++){
		dd[i] = (d[i] - a[i]*dd[i-1])/(b[i] - a[i]*cc[i-1]);
	}

	x[n-1] = dd[n-1];
	for(int i=n-2; i>=0; i--){
		x[i] = dd[i] - cc[i]*x[i+1];
	}
}

double q[MAX_N];

int main(){
	int R, C;
	while(scanf("%d %d", &N, &M)!=EOF){
		scanf("%d %d", &R, &C);
		R--; C--;

		if(M==1){
			printf("%.10lf\n", (2.0*(N-1.0)));
			continue;
		}

		for(int i=0; i<M; i++){
			a[i] = -0.25;
			b[i] = 3.0/4.0;
			c[i] = -0.25;
			q[i] = 0.0;
		}
		a[0] = 0.0;
		a[M-1] = -1.0/3.0;
		b[0] = 2.0/3.0;
		b[M-1] = 2.0/3.0;
		c[0] = -1.0/3.0;
		c[M-1] = 0.0;

		for(int i=N-2; i>=R; i--){
			for(int j=0; j<M; j++){
				if((j==0) || (j==(M-1))){
					d[j] = 1.0 + (1.0*q[j])/3.0;
				}
				else{
					d[j] = 1.0 + (1.0*q[j])/4.0;
				}
			}
			solve_trigonal(M);
			for(int j=0; j<M; j++){
				q[j] = x[j];
			}
		}

		printf("%.10lf\n", x[C]);
	}
	return 0;
}


#include <bits/stdc++.h>
#define eps 1e-6
#define LL long long
#define pii pair<int, int>
#define pb push_back
#define mp make_pair
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

const int MAXN = 1100;
//const int MOD = 1e9+7;
//const int INF = 0x3f3f3f3f;
int n, m, h, w;
double a[MAXN], b[MAXN], c[MAXN], d[MAXN], x[MAXN], dp[MAXN][MAXN];
void TDMA(int l, int n, int m) {
	for (int i = 1; i < n; i++)
		c[i] = c[i] / (b[i]-c[i-1]*a[i]);
	for (int i = 1; i <= n; i++)
		d[i] = (d[i]-d[i-1]*a[i])/(b[i]-c[i-1]*a[i]);
	dp[l][n] = d[n];
	for (int i = n-1; i >= 1; i--)
		dp[l][i] = d[i] - c[i]*dp[l][i+1];
}
int main()
{
	//freopen("input.txt", "r", stdin);
	scanf("%d%d%d%d", &n, &m, &h, &w);
	if (m == 1) {
		printf("%.8f", (double)(n-h)*2.0);
		return 0;
	}
	for (int i = n-1; i >= h; i--) {
		b[1] = 2.0/3;
		c[1] = -1.0/3;
		d[1] = 1+dp[i+1][1]/3;
		if (m > 1) {
			b[m] = 2.0/3;
			a[m] = -1.0/3;
			d[m] = 1+dp[i+1][m]/3;
		}
		for (int j = 2; j < m; j++) {
			a[j] = c[j] = -1.0/4;
			b[j] = 3.0/4;
			d[j] = 1 + dp[i+1][j]/4;
		}
		TDMA(i, m, m);
	}
	printf("%.8f", dp[h][w]);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<algorithm>
using namespace std;
#define MAXN 2050
int n, m, x, y;
double a[MAXN][MAXN], f[MAXN];
double Div;
inline int read() {
	int s = 0, w = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
	for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) +  (c ^ 48);
	return s * w;
}
void Guass() {
	a[1][1] = 2, a[1][2] = -1;
	for (register int i = 2; i <= m - 1; i++)
		a[i][i - 1] = -1, a[i][i] = 3, a[i][i + 1] = -1;
	a[m][m - 1] = -1, a[m][m] = 2;
	a[1][m + 1] = 3 + f[1];
	for (register int i = 2; i <= m - 1; i++)
		a[i][m + 1] = 4 + f[i];
	a[m][m + 1] = 3 + f[m];
	for (register int i = 2; i <= m; i++) {
		Div = a[i][i - 1] / a[i - 1][i - 1];
		a[i][i - 1] = 0;
		a[i][i] -= a[i - 1][i] * Div;
		a[i][m + 1] -= a[i - 1][m + 1] * Div;
	}
	f[m] = a[m][m + 1] / a[m][m];
	for (register int i = m - 1; i >= 1; i--)
		f[i] = (a[i][m + 1] - a[i][i + 1] * f[i + 1]) / a[i][i];
}
int main() {
	n = read(), m = read(), x = read(), y = read();
	if (m == 1) {
		printf("%.10f", 2.0 * (n - x));
		return 0;
	}
	if (x == n) {
		printf("%.10f", f[y]);
		return 0;
	}
	for (register int i = n - 1; i >= 1; i--) {
		Guass();
		if (i == x) {
			printf("%.10f", f[y]);
			break;
		}
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<algorithm>
using namespace std;
#define MAXN 1050
int n, m, x, y;
double a[MAXN][MAXN], f[MAXN];
double Div;
inline int read() {
	int s = 0, w = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
	for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) +  (c ^ 48);
	return s * w;
}
void Guass() {
	a[1][1] = 2, a[1][2] = -1;
	for (register int i = 2; i <= m - 1; i++)
		a[i][i - 1] = -1, a[i][i] = 3, a[i][i + 1] = -1;
	a[m][m - 1] = -1, a[m][m] = 2;
	a[1][m + 1] = 3 + f[1];
	for (register int i = 2; i <= m - 1; i++)
		a[i][m + 1] = 4 + f[i];
	a[m][m + 1] = 3 + f[m];
	for (register int i = 2; i <= m; i++) {
		Div = a[i][i - 1] / a[i - 1][i - 1];
		a[i][i - 1] = 0;
		a[i][i] -= a[i - 1][i] * Div;
		a[i][m + 1] -= a[i - 1][m + 1] * Div;
	}
	f[m] = a[m][m + 1] / a[m][m];
	for (register int i = m - 1; i >= 1; i--)
		f[i] = (a[i][m + 1] - a[i][i + 1] * f[i + 1]) / a[i][i];
}
int main() {
	n = read(), m = read(), x = read(), y = read();
	if (x == n) {
		printf("%.10f", f[y]);
		return 0;
	}
	for (register int i = n - 1; i >= 1; i--) {
		Guass();
		if (i == x) {
			printf("%.10f", f[y]);
			break;
		}
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<algorithm>
using namespace std;
#define MAXN 1050
int n, m, x, y;
double a[MAXN][MAXN], f[MAXN];
double Div;
inline int read() {
	int s = 0, w = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
	for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) +  (c ^ 48);
	return s * w;
}
void Guass() {
	a[1][1] = 2, a[1][2] = -1;
	for (register int i = 2; i <= m - 1; i++)
		a[i][i - 1] = -1, a[i][i] = 3, a[i][i + 1] = -1;
	a[m][m - 1] = -1, a[m][m] = 2;
	a[1][m + 1] = 3 + f[1];
	for (register int i = 2; i <= m - 1; i++)
		a[i][m + 1] = 4 + f[i];
	a[m][m + 1] = 3 + f[m];
	for (register int i = 2; i <= m; i++) {
		Div = a[i][i - 1] / a[i - 1][i - 1];
		a[i][i - 1] = 0;
		a[i][i] -= a[i - 1][i] * Div;
		a[i][m + 1] -= a[i - 1][m + 1] * Div;
	}
	f[m] = a[m][m + 1] / a[m][m];
	for (register int i = m - 1; i >= 1; i--)
		f[i] = (a[i][m + 1] - a[i][i + 1] * f[i + 1]) / a[i][i];
}
int main() {
	n = read(), m = read(), x = read(), y = read();
	if (m == 1) {
		printf("%d.0000000000", 2 * (n - 1));
		return 0;
	}
	if (x == n) {
		printf("%.10f", f[y]);
		return 0;
	}
	for (register int i = n - 1; i >= 1; i--) {
		Guass();
		if (i == x) {
			printf("%.10f", f[y]);
			break;
		}
	}
	return 0;
}


//#include<bits/stdc++.h>
#include<cmath>
#include<ctime>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define db double
#define ll long long
#define lb long double
#define ull unsigned long long
#define debug() puts("FBI WARNING!")
#define Abs(a) (a) < 0 ? (-a) : (a)
#define Max(a,b) (a) < (b) ? (b) : (a)
#define Min(a,b) (a) < (b) ? (b) : (a)

using namespace std;
const int P = 19260817;
const int MAX = 3000 + 5;
inline int read(){
	int f = 1, x = 0; char ch;
	do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
	do {x = x * 10 + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
	return f * x;
}

int n, m, x, y;
db f[MAX], mar[MAX][MAX], g[MAX];

int main(){
	n = read(), m = read(), x = read(), y = read();
	if (n == x) {
		puts("0.00000000");
		return 0;
	}
	for (int i = 1;i <= m; ++i) f[i] = 0;
	for (int i = n - 1;i >= x; --i) {

		g[1] = -3.0 - f[1], g[m] = -3.0 - f[m];
		for (int j = 2;j < m; ++j) g[j] = -4.0 - f[j];

		mar[1][1] = mar[m][m] = -2.0, mar[1][2] = mar[m][m - 1] = 1.0;
		for (int j = 2;j < m; ++j) {
			mar[j][j] = -3.0;
			mar[j][j - 1] = mar[j][j + 1] = 1.0;
		}

		for (int j = 1;j < m; ++j) {
			db tmp = mar[j + 1][j] / mar[j][j];
			mar[j + 1][j] -= tmp * mar[j][j];
			mar[j + 1][j + 1] -= tmp * mar[j][j + 1];
			g[j + 1] -= g[j] * tmp;
		}

//		for (int j = 1;j <= m; ++j) {
//			for (int k = 1;k <= m; ++k) {
//				printf("%.lf ", mar[j][k]);
//			}
//			puts("");
//		}

		f[m] = g[m] / mar[m][m];
		for (int j = m - 1;j >= 1; --j) f[j] = (g[j] - mar[j][j + 1] * f[j + 1]) / mar[j][j];
	}
	printf("%.8lf", f[y]);
	return 0;
}


//#include<bits/stdc++.h>
#include<cmath>
#include<ctime>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define db double
#define ll long long
#define lb long double
#define ull unsigned long long
#define debug() puts("FBI WARNING!")
#define Abs(a) (a) < 0 ? (-a) : (a)
#define Max(a,b) (a) < (b) ? (b) : (a)
#define Min(a,b) (a) < (b) ? (b) : (a)

using namespace std;
const int P = 19260817;
const int MAX = 3000 + 5;
inline int read(){
	int f = 1, x = 0; char ch;
	do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
	do {x = x * 10 + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
	return f * x;
}

int n, m, x, y;
db f[MAX], mar[MAX][MAX], g[MAX];

int main(){
	n = read(), m = read(), x = read(), y = read();
	if (n == x) {
		puts("0.00000000");
		return 0;
	}
	if (m == 1) {
		db res = 0;
		for (int i = n - 1;i >= x; --i) res += 2;
		printf("%.10lf", res);
		return 0;
	}

	for (int i = 1;i <= m; ++i) f[i] = 0;
	for (int i = n - 1;i >= x; --i) {

		g[1] = -3.0 - f[1], g[m] = -3.0 - f[m];
		for (int j = 2;j < m; ++j) g[j] = -4.0 - f[j];

		mar[1][1] = mar[m][m] = -2.0, mar[1][2] = mar[m][m - 1] = 1.0;
		for (int j = 2;j < m; ++j) {
			mar[j][j] = -3.0;
			mar[j][j - 1] = mar[j][j + 1] = 1.0;
		}

		for (int j = 1;j < m; ++j) {
			db tmp = mar[j + 1][j] / mar[j][j];
			mar[j + 1][j] -= tmp * mar[j][j];
			mar[j + 1][j + 1] -= tmp * mar[j][j + 1];
			g[j + 1] -= tmp * g[j];
		}

//		for (int j = 1;j <= m; ++j) {
//			for (int k = 1;k <= m; ++k) {
//				printf("%.lf ", mar[j][k]);
//			}
//			puts("");
//		}

		f[m] = g[m] / mar[m][m];
		for (int j = m - 1;j >= 1; --j) f[j] = (g[j] - mar[j][j + 1] * f[j + 1]) / mar[j][j];
	}
	printf("%.8lf", f[y]);
	return 0;
}


//#include<bits/stdc++.h>
#include<cmath>
#include<ctime>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define db double
#define ll long long
#define lb long double
#define ull unsigned long long
#define debug() puts("FBI WARNING!")
#define Abs(a) (a) < 0 ? (-a) : (a)
#define Max(a,b) (a) < (b) ? (b) : (a)
#define Min(a,b) (a) < (b) ? (b) : (a)

using namespace std;
const int P = 19260817;
const int MAX = 3000 + 5;
inline int read(){
	int f = 1, x = 0; char ch;
	do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
	do {x = x * 10 + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
	return f * x;
}

int n, m, x, y;
db f[2][MAX], mar[MAX][MAX], g[MAX];

int main(){
	n = read(), m = read(), x = read(), y = read();
	if (m == 1) {
		g[n] = 0;
		for (int i = n - 1;i >= x; --i) {
			g[i] = g[i + 1] + 2;
		}
		printf("%.4lf", g[x]);
	}
	for (int i = 1;i <= m; ++i) f[0][i] = 0;
	int s = 1;
	for (int i = n - 1;i >= x; --i, s ^= 1) {

		g[1] = -3.0 - f[s ^ 1][1], g[m] = -3.0 - f[s ^ 1][m];
		for (int j = 2;j < m; ++j) g[j] = -4.0 - f[s ^ 1][j];

		mar[1][1] = mar[m][m] = -2.0, mar[1][2] = mar[m][m - 1] = 1.0;
		for (int j = 2;j < m; ++j) {
			mar[j][j] = -3.0;
			mar[j][j - 1] = mar[j][j + 1] = 1.0;
		}

		for (int j = 1;j < m; ++j) {
			db tmp = mar[j + 1][j] / mar[j][j];
			for (int k = j;k <= j + 1; ++k) {
				mar[j + 1][k] -= mar[j][k] * tmp;
			}
			g[j + 1] -= g[j] * tmp;
		}

		for (int j = m;j >= 1; --j) f[s][j] = (g[j] - mar[j][j + 1] * f[s][j + 1]) / mar[j][j];
	}
	printf("%.4lf", f[s ^ 1][y]);
	return 0;
}


//#include<bits/stdc++.h>
#include<cmath>
#include<ctime>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define db double
#define ll long long
#define lb long double
#define ull unsigned long long
#define debug() puts("FBI WARNING!")
#define Abs(a) (a) < 0 ? (-a) : (a)
#define Max(a,b) (a) < (b) ? (b) : (a)
#define Min(a,b) (a) < (b) ? (b) : (a)

using namespace std;
const int P = 19260817;
const int MAX = 3000 + 5;
inline int read(){
	int f = 1, x = 0; char ch;
	do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
	do {x = x * 10 + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
	return f * x;
}

int n, m, x, y;
db f[2][MAX], mar[MAX][MAX], g[MAX];

int main(){
	n = read(), m = read(), x = read(), y = read();
	if (n == x) {
		puts("0.0000");
		return 0;
	}
	for (int i = 1;i <= m; ++i) f[0][i] = 0;
	int s = 1;
	for (int i = n - 1;i >= x; --i, s ^= 1) {

		g[1] = -3.0 - f[s ^ 1][1], g[m] = -3.0 - f[s ^ 1][m];
		for (int j = 2;j < m; ++j) g[j] = -4.0 - f[s ^ 1][j];

		mar[1][1] = mar[m][m] = -2.0, mar[1][2] = mar[m][m - 1] = 1.0;
		for (int j = 2;j < m; ++j) {
			mar[j][j] = -3.0;
			mar[j][j - 1] = mar[j][j + 1] = 1.0;
		}

		for (int j = 1;j < m; ++j) {
			db tmp = mar[j + 1][j] / mar[j][j];
			for (int k = j;k <= j + 1; ++k) {
				mar[j + 1][k] -= mar[j][k] * tmp;
			}
			g[j + 1] -= g[j] * tmp;
		}

		for (int j = m;j >= 1; --j) f[s][j] = (g[j] - mar[j][j + 1] * f[s][j + 1]) / mar[j][j];
	}
	printf("%.4lf", f[s ^ 1][y]);
	return 0;
}


//#include<bits/stdc++.h>
#include<cmath>
#include<ctime>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define db double
#define ll long long
#define lb long double
#define ull unsigned long long
#define debug() puts("FBI WARNING!")
#define Abs(a) (a) < 0 ? (-a) : (a)
#define Max(a,b) (a) < (b) ? (b) : (a)
#define Min(a,b) (a) < (b) ? (b) : (a)

using namespace std;
const int P = 19260817;
const int MAX = 3000 + 5;
inline int read(){
	int f = 1, x = 0; char ch;
	do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
	do {x = x * 10 + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
	return f * x;
}

int n, m, x, y;
db f[MAX], mar[MAX][MAX], g[MAX];

int main(){
	n = read(), m = read(), x = read(), y = read();
	if (n == x) {
		puts("0.00000000");
		return 0;
	}
	if (m == 1) {
		db res = 0;
		for (int i = n;i >= x; --i) res += 2;
		printf("%.10lf", res);
		return 0;
	}
	for (int i = 1;i <= m; ++i) f[i] = 0;
	for (int i = n - 1;i >= x; --i) {

		g[1] = -3.0 - f[1], g[m] = -3.0 - f[m];
		for (int j = 2;j < m; ++j) g[j] = -4.0 - f[j];

		mar[1][1] = mar[m][m] = -2.0, mar[1][2] = mar[m][m - 1] = 1.0;
		for (int j = 2;j < m; ++j) {
			mar[j][j] = -3.0;
			mar[j][j - 1] = mar[j][j + 1] = 1.0;
		}

		for (int j = 1;j < m; ++j) {
			db tmp = mar[j + 1][j] / mar[j][j];
			mar[j + 1][j] -= tmp * mar[j][j];
			mar[j + 1][j + 1] -= tmp * mar[j][j + 1];
			g[j + 1] -= tmp * g[j];
		}

//		for (int j = 1;j <= m; ++j) {
//			for (int k = 1;k <= m; ++k) {
//				printf("%.lf ", mar[j][k]);
//			}
//			puts("");
//		}

		f[m] = g[m] / mar[m][m];
		for (int j = m - 1;j >= 1; --j) f[j] = (g[j] - mar[j][j + 1] * f[j + 1]) / mar[j][j];
	}
	printf("%.8lf", f[y]);
	return 0;
}