/*
 * IPSC 2001
 * Problem D, Urvi komu urvi
 * (c) palenica
 */

#include <stdio.h>
#include <assert.h>

const int MAXN = 5000;
const int INFTY = 100000000;

struct node {
  int boss,    // pointer to parent
      cost,    // cost of the edge to boss
      deg,     // number of children 
      size,    // size of the subtree rooted at this node
      lt, rt,  // left/right sibling
      bol, tmp,// flag for DFS
      team;    // the definitive answer
  int *ch,     // list of children
      *p, *q, *maxi;  // the DP arrays
};

FILE *f;
int N, root, totalcost;
node b[MAXN+1];
int *dummy;

inline int max2(int a, int b) { return (a>b)?a:b; }

void DFS(int v)
{
  int i, k, deg, size, lt, i0;
  int *p, *pu, *q;
  deg = b[v].deg;
  size = 1;

  for(i=0; i<deg; i++) {
    DFS(b[v].ch[i]);
    size += b[b[v].ch[i]].size;
  }
  b[v].size = size;

  if (deg==0) { //leaf
    b[v].q = dummy;
  } else {
    b[v].q = b[b[v].ch[deg-1]].p;
  }
  p = new int[N+1];
  b[v].maxi = new int[N+1];
  assert(p && b[v].maxi); b[v].p = p;
  lt = b[v].lt;
  q = b[v].q;

  if (lt <= 0) { // v has no left sibling
    pu = dummy;
  } else { // v has a left sibling
    pu = b[b[v].lt].p;
  }
  for(k=0; k<=N; k++) {
    p[k] = -INFTY;
    for(i=0; i<=k; i++) if (p[k] < pu[i] + q[k-i]) {
      p[k] = pu[i] + q[k-i];
      b[v].maxi[k] = i;
    }

    i0 = (k-size>0)?(k-size):0;
    for(i=i0; i<=k; i++) if (p[k] < pu[i] + q[size-k+i] + b[v].cost) {
      p[k] = pu[i] + q[size-k+i] + b[v].cost;
      b[v].maxi[k] = MAXN+i;
    }
  }
}

void TeamIt(int v, int team, int num)
{
  int i, deg, ch, ii;
  b[v].team = team;
  deg = b[v].deg;
  for(i=deg-1; i>=0; i--) {
    ch = b[v].ch[i];
    ii = b[ch].maxi[num];
    if (ii<MAXN) {
      TeamIt(ch, team, num-ii);
    } else {
      ii -= MAXN;
      TeamIt(ch, 1-team, b[ch].size-num+ii);
    }
    num = ii;
  }
}

void PrintIt()
{
  int i, bol;
  for(i=1, bol=0; i<=N; i++)
    if (b[i].team==0) printf(!(bol++)?"%d":" %d", i);
  printf("\n");
}

int main(int argc, char **argv)
{
  int i, j, boss, deg;
      totalcost;

  if (argc>1) f = fopen(argv[1], "r");
  else f = fopen("urvi.in", "r");

  fscanf(f,"%d ", &N);
  if (N>=MAXN || N%2!=0) {
    printf("N must be even!\n");
    return -1;
  }

  for(i=0; i<=N; i++) 
    b[i].deg = b[i].size = 0;

  totalcost = 0;
  for(i=1; i<=N; i++) {
    fscanf(f, "%d %d ", &b[i].boss, &b[i].cost);
    if (b[i].boss == 0) root = i;
    b[b[i].boss].deg++;
    totalcost += b[i].cost;
  }
  assert(b[0].deg==1); // exactly one root

  for(i=1; i<=N; i++) {
    b[i].ch = new int[N];
    assert(b[i].ch);
    b[i].tmp = 0;
    b[i].lt = b[i].rt = -1;
  }
  for(i=1; i<=N; i++) { // initializing child links
    boss = b[i].boss;
    if (boss<=0) continue;
    b[boss].ch[b[boss].tmp++] = i;
  }
  for(i=1; i<=N; i++) { // initializing left/right sibling pointers
    deg = b[i].deg;
    if (deg==0) continue;
    for(j=0; j<deg-1; j++) {
      b[b[i].ch[j]].rt = b[i].ch[j+1];
      b[b[i].ch[j+1]].lt = b[i].ch[j];
    }
    //b[b[i].ch[0]].lt = -1;
    //b[b[i].ch[deg-1]].rt = -1;
  }

  dummy = new int[N+1];
  assert(dummy);
  dummy[0] = 0; for(i=1; i<=N; i++) dummy[i] = -INFTY;
  // constant array used to start induction at leaves

  DFS(root);
  TeamIt(root, 0, N/2);
  PrintIt();

  //printf("Cost: %d Total cost of all edges in the tree: %d\n",b[root].p[N/2], totalcost);

  // deallocation
  /*
  for(i=1; i<=N; i++) {
    delete[] b[i].ch;
    if (b[i].deg>0) { delete[] b[i].p; }
    delete[] b[i].maxi;
  }
  delete[] dummy;
   */
  fclose(f); 
  
  return 0;
}
