/*
TASK:sym
LANG:C
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define MAX 10001
#define min(a,b) ((a<b)?a:b)
#define max(a,b) ((a>b)?a:b)

typedef struct {
	int x, y;
	int used;
	int ind;
} point;

typedef struct {
	double x, y;
	int ind;
	int used;
} point_d;

typedef struct {
	double d1, d2;
	int ind;
} dist_d;

int n;
point_d points[MAX];
point_d orig[MAX];
point_d p1, p2;
double dist_p1[MAX];
double dist_p2[MAX];

dist_d dists[MAX];

int cmp(point *x, point *y) {
	double dx, dy;
	dx = (x->x) - (y->x);
	dy = (x->y) - (y->y);

	if (dx != 0) {
		return (int)dx;
	} else {
		return (int)dy;
	}
}

int cmp_dist(dist_d *x, dist_d *y) {
	double dx, dy;
	dx = (x->d1) - (y->d1);
	dy = (x->d2) - (y->d2);

	if (dx > 0) {
		return 1;
	} else {
		return -1;
	}
}

double angle(int x1, int y1, int x2, int y2) {
	if (x1 == x2) return 1;
	return ((y1 - y2) / (x1 - x2));
}

double middle_x(double x1, double x2) {
	return (double)min(x1, x2) + ((double)fabs(x1-x2)/2);
}

double middle_y(double y1, double y2) {
	return (double)min(y1, y2) + ((double)fabs(y1-y2)/2);
}

double dist(point_d *p1, point_d *p2) {
	double d = (double)(p1->x - p2->x)*(p1->x - p2->x) + (double)(p1->y - p2->y) * (p1->y - p2->y);
	return sqrt( (double)d );
}

int find_far(int p) {
	int i, mi;
	double d, m;

	mi = -1;
	m = 0.0;

	for (i=0; i<n; i++) {
		if (!points[i].used) {
			d = dist(&points[p], &points[i]);
			if (d > m) {
				m = d;
				mi = i;
			}
		}
	}

	return mi;
}

int det(point_d *p1, point_d *p2, point_d *p3) {
	return (p1->x * p2->y + p1->y * p3->x + p2->x * p3->y) -
		   (p2->y * p3->x + p1->y * p2->x + p1->x * p3->y);
}

int find_point(point_d *p) {
	int i, j;

	i = 0;

	while (points[i].used) {
		i++;
	}

	j = find_far(i);
	points[j].used = 1;

	if (dist(&points[find_far(i)], &points[i]) == dist(&points[i], &points[j])) {
		// point i is correct
		points[i].used = 1;
		points[j].used = 0;

		p->x = points[i].x;
		p->y = points[i].y;
		return 0;
	}

	i = find_far(j);
	points[i].used = 1;

	if (dist(&points[find_far(j)], &points[j]) == dist(&points[i], &points[j])) {
		// point j is correct
		points[i].used = 0;
		points[j].used = 1;

		p->x = points[j].x;
		p->y = points[j].y;
		return 0;
	}

 	points[i].used = 1;
	points[j].used = 1;

	p->x = middle_x(points[i].x, points[j].x);
	p->y = middle_y(points[i].y, points[j].y);

	return 0;	
}

int main() {
	int i;
	int result[MAX] = {0};
	int last;

	scanf("%d", &n);

	for (i=0; i<n; i++) {
		scanf("%lf %lf", &points[i].x, &points[i].y);

		orig[i].x = points[i].x;
		orig[i].y = points[i].y;

		points[i].used = 0;
		points[i].ind = i;
	}

	qsort(&points[0], n, sizeof(point_d), cmp);

	find_point(&p1);

	while (1) {
		find_point(&p2);

		if (p2.x != p1.x || p2.y != p1.y) {
			//printf("(%.3f,%.3f),(%.3f,%.3f)\n", p1.x, p1.y, p2.x, p2.y);
			break;
		}
	}

	for (i=0; i<n; i++) {
		dists[i].ind = points[i].ind;
		dists[i].d1 = dist(&points[i], &p1);
		dists[i].d2 = dist(&points[i], &p2); 
	}

	qsort(&dists[0], n, sizeof(dist_d), cmp_dist);

	last = -1;

	for (i=0; i<n; i++) {
		if (det(&orig[dists[i].ind], &p1, &p2) == 0) {
			//printf("%d - on sym\n", dists[i].ind);
			result[dists[i].ind] = dists[i].ind + 1;
		} else {
			if (last != -1) {
				if (dists[last].d1 == dists[i].d1 && dists[last].d2 == dists[i].d2) {
					result[dists[i].ind] = dists[last].ind + 1;
					result[dists[last].ind] = dists[i].ind + 1;
					last = -1;
				}
			} else {
				last = i;
			}

			//printf("%d - %3.3f,%3.3f\n", dists[i].ind, dists[i].d1, dists[i].d2);
		}
	}

	for (i = 0; i<n; i++) {
		if (!result[i]) {
			printf("0\n");
			return 0;
		}
	}

	for (i = 0; i<n; i++) {
		printf("%d ", result[i]);
	}
	printf("\n");

	return 0;
}