#include <bits/stdc++.h>
#pragma comment(linker, "/stack:512000000")
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
mt19937_64 gen(time(NULL));
ll const mod = 998244353;
namespace {
ll mul(ll a, ll b) {
  ll val = a * b - (ll)((ld)a * b / mod) * mod;
  if (val < 0) val += mod;
  if (val >= mod) val -= mod;
  return val;
}
ll poww(ll a, ll b) {
  ll val = 1;
  a %= mod;
  while (b > 0) {
    if (b % 2) val = mul(a, val);
    a = mul(a, a);
    b >>= 1;
  }
  return val % mod;
}
ll inv(ll a) { return poww(a, mod - 2); }
}  // namespace
int const maxn = 3e5 + 5;
struct sumtree {
  struct node {
    node(ll x) : val(x){};
    node() : val(0){};
    ll val = 0;
    ll lazy = 0;
    void apply(int tl, int tr, ll add) {
      val += add * (tr - tl + 1);
      lazy += add;
    }
  };
  void push(int u, int tl, int tr) {
    if (t[u].lazy != 0) {
      int tm = (tl + tr) / 2;
      t[u * 2].apply(tl, tm, t[u].lazy);
      t[u * 2 + 1].apply(tm + 1, tr, t[u].lazy);
      t[u].lazy = 0;
    }
  }
  node merge(const node& a, const node& b) const { return node(a.val + b.val); }
  node get(int u, int tl, int tr, int l, int r) {
    if (r < l || tl > r || tr < l) {
      return neutral;
    }
    if (l <= tl && tr <= r) {
      return t[u];
    } else {
      push(u, tl, tr);
      int tm = (tl + tr) / 2;
      return merge(get(u * 2, tl, tm, l, r), get(u * 2 + 1, tm + 1, tr, l, r));
    }
  }
  template <typename... M>
  void upd(int u, int tl, int tr, int l, int r, const M&... m) {
    if (r < l || tl > r || tr < l) {
      return;
    }
    if (l <= tl && tr <= r) {
      t[u].apply(tl, tr, m...);
    } else {
      push(u, tl, tr);
      int tm = (tl + tr) / 2;
      upd(u * 2, tl, tm, l, r, m...);
      upd(u * 2 + 1, tm + 1, tr, l, r, m...);
      t[u] = merge(t[u * 2], t[u * 2 + 1]);
    }
  }
  template <class T>
  void build(int u, int tl, int tr, vector<T>& v) {
    if (tl == tr) {
      node tmp(v[tl]);
      t[u] = tmp;
    } else {
      int tm = (tl + tr) / 2;
      build(u * 2, tl, tm, v);
      build(u * 2 + 1, tm + 1, tr, v);
      t[u] = merge(t[u * 2], t[u * 2 + 1]);
    }
  }
  void casual_build(int u, int tl, int tr) {
    if (tl == tr) {
      return;
    } else {
      int tm = (tl + tr) / 2;
      casual_build(u * 2, tl, tm);
      casual_build(u * 2 + 1, tm + 1, tr);
      t[u] = merge(t[u * 2], t[u * 2 + 1]);
    }
  }
  sumtree(ll n) : n(n) {
    t.resize(4 * n);
    casual_build(1, 0, n - 1);
  }
  template <class T>
  sumtree(vector<T>& v) : n(v.size()) {
    t.resize(4 * n);
    build(1, 0, n - 1, v);
  }
  node get(int l, int r) { return get(1, 0, n - 1, l, r); }
  template <typename... M>
  void upd(int l, int r, const M&... m) {
    upd(1, 0, n - 1, l, r, m...);
  }
  int n;
  vector<node> t;
  node neutral;
};
struct segtree {
  struct node {
    node(ll x) : val_mx(x){};
    node() : val_mx(LLONG_MIN){};
    ll val_mx = LLONG_MIN;
    ll lazy = 0;
    void apply(int tl, int tr, ll add) {
      val_mx += add;
      lazy += add;
    }
  };
  void push(int u, int tl, int tr) {
    if (t[u].lazy != 0) {
      int tm = (tl + tr) / 2;
      t[u * 2].apply(tl, tm, t[u].lazy);
      t[u * 2 + 1].apply(tm + 1, tr, t[u].lazy);
      t[u].lazy = 0;
    }
  }
  node merge(const node& a, const node& b) const {
    return node(max(a.val_mx, b.val_mx));
  }
  node get(int u, int tl, int tr, int l, int r) {
    if (r < l || tl > r || tr < l) {
      return neutral;
    }
    if (l <= tl && tr <= r) {
      return t[u];
    } else {
      push(u, tl, tr);
      int tm = (tl + tr) / 2;
      return merge(get(u * 2, tl, tm, l, r), get(u * 2 + 1, tm + 1, tr, l, r));
    }
  }
  template <typename... M>
  void upd(int u, int tl, int tr, int l, int r, const M&... m) {
    if (r < l || tl > r || tr < l) {
      return;
    }
    if (l <= tl && tr <= r) {
      t[u].apply(tl, tr, m...);
    } else {
      push(u, tl, tr);
      int tm = (tl + tr) / 2;
      upd(u * 2, tl, tm, l, r, m...);
      upd(u * 2 + 1, tm + 1, tr, l, r, m...);
      t[u] = merge(t[u * 2], t[u * 2 + 1]);
    }
  }
  template <class T>
  void build(int u, int tl, int tr, vector<T>& v) {
    if (tl == tr) {
      node tmp(v[tl]);
      t[u] = tmp;
    } else {
      int tm = (tl + tr) / 2;
      build(u * 2, tl, tm, v);
      build(u * 2 + 1, tm + 1, tr, v);
      t[u] = merge(t[u * 2], t[u * 2 + 1]);
    }
  }
  void casual_build(int u, int tl, int tr) {
    if (tl == tr) {
      return;
    } else {
      int tm = (tl + tr) / 2;
      casual_build(u * 2, tl, tm);
      casual_build(u * 2 + 1, tm + 1, tr);
      t[u] = merge(t[u * 2], t[u * 2 + 1]);
    }
  }
  segtree(ll n) : n(n) {
    t.resize(4 * n);
    casual_build(1, 0, n - 1);
  }
  template <class T>
  segtree(vector<T>& v) : n(v.size()) {
    t.resize(4 * n);
    build(1, 0, n - 1, v);
  }
  node get(int l, int r) { return get(1, 0, n - 1, l, r); }
  template <typename... M>
  void upd(int l, int r, const M&... m) {
    upd(1, 0, n - 1, l, r, m...);
  }
  int n;
  vector<node> t;
  node neutral;
};
ll pos[maxn];
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ll n;
  cin >> n;
  vector<ll> p(n), a(n);
  for (ll i = 0; i < n; i++) {
    cin >> p[i];
    pos[p[i]] = i;
  }
  for (ll i = 0; i < n; i++) {
    cin >> a[i];
  }
  vector<ll> tmp(n);
  segtree st(tmp);
  segtree sum(tmp);
  ll cur = n;
  st.upd(0, pos[n], 1);
  ll mx = 1;
  for (ll i = 0; i < n; i++) {
    cout << cur << " ";
    if (i == n - 1) {
      break;
    }
    ll qq = a[i] - 1;
    st.upd(0, qq, -1);
    mx = st.get(0, n - 1).val_mx;
    while (mx <= 0) {
      cur--;
      assert(cur >= 1);
      st.upd(0, pos[cur], 1);
      mx = st.get(0, n - 1).val_mx;
    }
  }
  return 0;
}
