/*
TASK:sym
LANG:C++
*/

#include <cstdlib>
#include <math.h>
#include <iostream>
#include <fstream>
#include <set>

using namespace std;
const double derr = 0.00000000000001;

struct mdouble {
	double v;
	mdouble() : v(0){}
	mdouble( const double& d ) : v(d){}

	bool operator<( const mdouble& md ) const {
		return v < md.v;
	}
	bool operator>( const mdouble& md ) const {
		return v > md.v;
	}
	bool operator==( const mdouble& md ) const {
		double d = v - md.v;
		if ( d > -derr && d < derr ) return true;
		return false;
	}
	
	bool operator<( const double& d ) const {
		return v < d;
	}
	bool operator>( const double& d ) const {
		return v > d;
	}
	bool operator==( const double& d ) const {
		double d2 = v - d;
		if ( d2 > -derr && d2 < derr ) return true;
		return false;
	}

	operator double& () {
		return v;
	}

	operator double* () {
		return &v;
	}

};


bool deq( const double& a, const double& b ) {
		double d2 = a - b;
		if ( d2 > -derr && d2 < derr ) return true;
		return false;
}

struct mdless {
	bool operator()( const double& a, const double& b ) {
		if ( deq( a, b ) ) return false;
		return a < b;
	}
};

struct mpoint {
	int num;
	double x;
	double y;
	double len2;
	mpoint() : x(0), y(0), num(-1), len2(0) {}
	mpoint( const mpoint& m ) : x(m.x), y(m.y), num(m.num), len2(m.len2) {}
	mpoint( const double& xc, const double& yc, const int& numc, const double& len2c ) :
		x(xc), y(yc), num( numc ), len2( len2c ) {}
	
	bool operator<( const mpoint& pnt ) const {
		if ( *this == pnt ) return false;
		return len2 < pnt.len2;
	}

	bool operator>( const mpoint& pnt ) const {
		if ( *this == pnt ) return false;
		return len2 > pnt.len2;
	}

	bool operator==( const mpoint& pnt ) const {
		return deq( x, pnt.x ) && deq( y, pnt.y );
	}
};
mpoint zpoint;

struct mline {
	bool vert;
	bool horz;
	//y = a*x+b
	double a;
	double b;
	mline() : vert(false), horz(true), a(0), b(0){}
	mline( const mpoint& pa, const mpoint& pb ) {
		if ( deq( pa.x, pb.x ) ) {
			vert = true;
			horz = false;
			a = pa.x;
		}
		else if ( deq( pa.y, pb.y ) ) {
			vert = false;
			horz = true;
			a = pa.y;
		}
		else {
			vert = false;
			horz = false;
			a = (pa.y - pb.y)/(pa.x - pb.x);
			b = pa.y - a*pa.x;
		}
	}

	void symm ( const mpoint& pa, mpoint& sa ) {
		if ( vert ) {
			sa.y = pa.y;
			sa.x = 2*a-pa.x;
		}
		else if ( horz ) {
			sa.x = pa.x;
			sa.y = 2*a-pa.y;
		}
		else {
			// See notebook for details
			sa.x = (pa.y - b)/a;
			sa.y = a*pa.x + b;
		}
	}

};

double len2( const mpoint& a ) {
	return a.x*a.x + a.y*a.y;
}

double dist2( const mpoint& a, const mpoint& b ) {
	double x = a.x - b.x;
	double y = a.y - b.y;
	return x*x + y*y;
}

double mcos2( const mpoint& a, const mpoint& b ) {
	double hip = dist2( a, b );
	double ks = a.x - b.x;
	return (ks*ks)/hip;
}

/*void symm( const mline& l, const mpoint& a, mpoint& sa ) {
}*/

typedef set<mpoint> mpset;
typedef set<double> mdset;
mpoint *pnts;
int *syms;
int nump;
mpset spnts;
mdset slns;

bool tryline( int p1, int p2 );

int main() {
#ifdef MFIN
	ifstream in( "sym.inp" );
#else
	istream& in = cin;
#endif
	in >> nump;
	if ( nump < 3 ) {
		for ( int i = 0; i < nump; ++i ) {
			cout << i << ' ';
		}
		cout << endl;
		return 0;
	}
	pnts = new mpoint[nump];
	syms = new int[nump];

	int i;
	double x, y;
	for ( i = 0; i < nump; ++i ) {
		in >> x >> y;
		pnts[i].x = x;
		pnts[i].y = y;
		pnts[i].num = i;
		pnts[i].len2 = len2( pnts[i] );
		spnts.insert( pnts[i] );
	}

#ifdef MFIN
	in.close();
#endif

	int j, k;
	bool cont = true;
	for ( i = 0; (i < nump - 1) && cont; ++i ) {
		for ( j = i+1; (j < nump) && cont; ++j ) {
			if ( tryline( i, j ) ) {
				cont = false;
				for ( k = 0; k < nump; ++k )
					cout << syms[k]+1 << ' ';
				cout << endl;
			}
		}
	}
	if( cont ) {
		cout << "0\n";
	}

	delete[] pnts;
	delete[] syms;
	return 0;
}


bool tryline( int p1, int p2 ) {
	// well, try all points
	// symmpoint
	mpoint sp;
	mline l( pnts[p1], pnts[p2] );
	if ( l.horz ) {
		l.horz = false;
		l.vert = true;
		l.a = (pnts[p1].x + pnts[p2].x) / 2;
	}
	else if ( l.vert ) {
		l.vert = false;
		l.horz = true;
		l.a = (pnts[p1].y + pnts[p2].y) / 2;
	}
	else {
		l.a = (pnts[p1].x - pnts[p2].x)/(pnts[p1].y - pnts[p2].y);
		l.b = pnts[p1].y - l.a*pnts[p2].x;
	}

	mpset::iterator iter;
	int i;
	for ( i = 0; i < nump; ++i ) {
		syms[i] = -1;
	}
	for ( i = 0; i < nump; ++i ) {
		if ( syms[i] != -1 ) continue;
		l.symm( pnts[i], sp );
		sp.len2 = len2( sp );
		iter = spnts.find( sp );
		if ( iter == spnts.end() || !( sp == *iter ) ) return false;
		syms[iter->num] = i;
		syms[i] = iter->num;
	}
	return true;
}
