#include <stdio.h>
#include <stdint.h>
#include <iostream>
#include <fstream>
#include <cassert>
#include <climits>
#include <vector>
using namespace std;

#define DEBUG (0)

#if DEBUG
#define DPRINTF(...) do { \
    printf("D(L%d) %s: ", __LINE__, __func__); \
    printf(__VA_ARGS__); \
  } while (false)
#else
#define DPRINTF(...)
#endif // DEBUG

/* binary tree */
struct Node {
  Node() :
    left_(-1),
    right_(-1) { }

  int left_;
  int right_;
};


int findIdxOf(int val, int start, int end, const int array[])
{
  for (int i = start; i <= end; i++)
  {
    if (array[i] == val)
      return i;
  }

  // The val must be found between start to end index
  assert(false);
}

int reconstructTree(Node *node, int start, int end, const int preorder[], const int inorder[])
{
  DPRINTF("start %d  end %d\n", start, end);

#if DEBUG
  if (true) {
    for (int i = start; i <= end; i++)
    {
      if (i == start) DPRINTF("preorder: %d", preorder[i]);
      else            printf(" %d", preorder[i]);
    }
    cout << endl;

    for (int i = start; i <= end; i++)
    {
      if (i == start) DPRINTF("inorder:  %d", inorder[i]);
      else            printf(" %d", inorder[i]);
    }
    cout << endl;
  }
#endif

  if (start == end)
    return preorder[start];

  if (start > end)
    return -1;

  // Determine which one is the root node
  int root = preorder[start];
  int center = findIdxOf(root, start, end, inorder);

  DPRINTF("root %d  center  %d\n", root, center);

  // Similarly, determine the root nodes of both the left and right trees
  // Note that pre-order array has to be alligned before dive into recursively
  //int newPreorder[center - start - 1];
  int newPreorder[center];
  for (int i = start; i < center; i++)
  {
    newPreorder[i] = preorder[i+1];
    DPRINTF("newPreorder[%d] %d\n", i, newPreorder[i]);
  }

  node[root].left_ = reconstructTree(node, start, center - 1, newPreorder, inorder);
  node[root].right_ = reconstructTree(node, center + 1, end, preorder, inorder);

  DPRINTF("node %d / left %d / right %d\n", root, node[root].left_, node[root].right_);

  return root;
}

void traversePostorder(const Node *node, int idx, bool &first)
{
  DPRINTF("idx %d\n", idx);

  if (&node[idx] == nullptr)
    return ;

  if (node[idx].left_ > -1)
    traversePostorder(node, node[idx].left_, first);

  if (node[idx].right_ > -1)
    traversePostorder(node, node[idx].right_, first);

  if (first)
  {
    printf("%d", idx);
    first = false;
  }
  else
    printf(" %d", idx);
}


int main()
{
  int numOfNode;
  cin >> numOfNode; cin.ignore();

  int arrayOfPreorder[numOfNode];
  int arrayOfInorder[numOfNode];

  for (int i = 0; i < numOfNode; i++)
    cin >> arrayOfPreorder[i];

  for (int i = 0; i < numOfNode; i++)
    cin >> arrayOfInorder[i];

#if DEBUG
  for (int i = 0; i < numOfNode; i++)
  {
    if (i == 0) DPRINTF("%d", arrayOfPreorder[i]);
    else        printf(" %d", arrayOfPreorder[i]);
  }
  cout << endl;

  for (int i = 0; i < numOfNode; i++)
  {
    if (i == 0) DPRINTF("%d", arrayOfInorder[i]);
    else        printf(" %d", arrayOfInorder[i]);
  }
  cout << endl;
#endif

  Node *nodes = new Node[numOfNode + 1];

  int start = 0;
  int end = numOfNode - 1;
  int rootIdx = reconstructTree(nodes, start, end, arrayOfPreorder, arrayOfInorder);

  bool first = true;
  traversePostorder(nodes, rootIdx, first);
  cout << endl;

  delete[] nodes;

  return 0;
}



Measured memory_bytes: 3216