/*
TASK:sym
LANG:C
*/

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

typedef struct SIntPair
{
  double x, y;
  short index;
} point;

typedef struct SFloTriple
{
  double a, b, c;
} line;

short N, ans[10000];
point p[10000];

int iszero(double x)
{
  if(x<0.00000001 && x>-0.00000001)
    return 1;
  return 0;
}

void lpts(line *a, point A, point B)
{
  if(A.x==B.x)
  {
    a->a=1;
    a->b=0;
    a->c=-A.x;
    return;
  }
  a->b=1;
  a->a=-((double)A.y-(double)B.y)/((double)A.x-(double)B.x);
  a->c=-(A.y+a->a*A.x);
}

void midpt(point *X, point A, point B)
{
  X->x=((double)A.x+(double)B.x)/2;
  X->y=((double)A.y+(double)B.y)/2;
}

void sym(line *a, point A, point B)
{
  static line b;
  static point M;
  lpts(&b, A, B);
  midpt(&M, A, B);
  if(iszero(b.a))
  {
    a->a=1;
    a->b=0;
    a->c= -M.x;
    return;
  }
  if(iszero(b.b))
  {
    a->a=0;
    a->b=1;
    a->c= -M.y;
  }
  a->a=tan(atan(b.a)+M_PI/2);
  a->b=1;
  a->c= -(a->a*M.x+(double)M.y);
}

int online(point A, line *a)
{
  return iszero(a->a*A.x+a->b*A.y+a->c);
}

void input(void)
{
  short i;
  scanf("%hd", &N);
  for(i=0; i<N; ++i)
  {
    scanf("%lf %lf", &p[i].x, &p[i].y);
    p[i].index=i;
  }
}

void swap(line *a, line *b)
{
  static line t;
  t=*a;
  *a=*b;
  *b=t;
}

void inter(line *a, line *b, point *X)
{
  static double t;
  if(iszero(a->a))
    swap(a, b);
  X->y=(a->c*b->a - b->c*a->a)/(a->a*b->b - b->a*a->b);
  X->x=-(a->b*X->y+a->c)/a->a;
}

void sympt(point A, line *a, point *X)
{
  line b;
  static point H;
  if(iszero(a->a))
  {
    b.a=1;
    b.b=0;
    b.c= -A.x;
  }
  else
    if(iszero(a->b))
    {
      b.a=0;
      b.b=1;
      b.c= -A.y;
    }
    else
    {
      b.a=tan(atan(a->a)+M_PI/2);
      b.b=1;
      b.c=-(b.a*A.x+(double)A.y);
    }
  inter(a, &b, &H);
  X->x=2.0*H.x-A.x;
  X->y=2.0*H.y-A.y;
}

int cmp(const void *a, const void *b)
{
  static point *A, *B;
  A=(point*)a;
  B=(point*)b;
  if(iszero(A->x-B->x))
  {
    if(iszero(A->y-B->y))
      return 0;
    if(A->y>B->y)
      return 1;
    if(A->y<B->y)
      return -1;
  }
  if(A->x>B->x)
    return 1;
  if(A->x<B->x)
    return -1;
}

int main(void)
{
  char f=0;
  short i, j;
  line s;
  point A, *X;
  input();
  lpts(&s, p[0], p[1]);
  for(i=2; i<N; ++i)
    if(!online(p[2], &s))
      break;
  if(i==N)
  {
    for(j=0; j<N; ++j)
      printf("%hd ", j+1);
    printf("\n");
    return 0;
  }
  qsort(p, N, sizeof(point), cmp);
  for(i=1; i<N; ++i)
  {
    sym(&s, p[0], p[i]);
    ans[p[0].index]=p[i].index;
    ans[p[i].index]=p[0].index;
    for(j=1; j<N; ++j)
      if(i!=j)
      {
        sympt(p[j], &s, &A);
        X=bsearch (&A, p, N, sizeof(point), cmp);
        if(X==NULL)
          break;
        ans[p[j].index]=X->index;
      }
    if(N==j)
    {
      f=1;
      break;
    }
  }
  if(!f)
    for(i=2; i<N; ++i)
    {
      sym(&s, p[1], p[i]);
      ans[p[1].index]=p[i].index;
      ans[p[i].index]=p[1].index;
      for(j=0; j<N; ++j)
        if(i!=j&&j!=1)
        {
          sympt(p[j], &s, &A);
          X=bsearch (&A, p, N, sizeof(point), cmp);
          if(X==NULL)
            break;
          ans[p[j].index]=X->index;
        }
      if(N==j)
      {
        f=1;
        break;
      }
    }
  if(!f)
  {
    lpts(&s, p[0], p[1]);
    ans[p[0].index]=p[0].index;
    ans[p[1].index]=p[1].index;
    for(j=2; j<N; ++j)
    {
      sympt(p[j], &s, &A);
      X=bsearch (&A, p, N, sizeof(point), cmp);
      if(X==NULL)
        break;
      ans[p[j].index]=X->index;
    }
    if(N==j)
      f=1;
  }
  if(f==0)
  {
    printf("0\n");
    return 0;
  }
  for(i=0; i<N; ++i)
    printf("%hd ", ans[i]+1);
  printf("\n");
  return 0;
}

