#include <bits/stdc++.h>
using namespace std;
const int maxn = 100001;
struct NODE {
  long long to_f, ex_f, t;
  set<pair<long long, int> > s;
  int f;
  int ind;
  NODE() { ind = to_f = ex_f = 0; }
  void upd_to_f();
  void set_ex_f(long long);
} v[maxn];
multiset<long long> gs;
inline void upd(int i) {
  if (!v[i].s.empty()) {
    gs.insert(v[i].s.begin()->first + v[i].to_f);
    gs.insert(v[i].s.rbegin()->first + v[i].to_f);
  }
}
inline void del(int i) {
  if (!v[i].s.empty()) {
    gs.erase(gs.find(v[i].s.begin()->first + v[i].to_f));
    gs.erase(gs.find(v[i].s.rbegin()->first + v[i].to_f));
  }
}
void NODE::upd_to_f() {
  int i = this - v;
  del(i);
  to_f = t / (ind + 2);
  upd(i);
}
void NODE::set_ex_f(long long _ex_f) {
  int i = this - v;
  del(f);
  v[f].s.erase({ex_f, i});
  v[f].s.insert({ex_f = _ex_f, i});
  upd(f);
}
int n, qq;
int ind[maxn] = {0};
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> qq;
  for (int i = 1; i <= n; i++) cin >> v[i].t;
  for (int i = 1; i <= n; i++) {
    cin >> v[i].f;
    v[v[i].f].ind++;
  }
  for (int u = 1; u <= n; u++) {
    int f = v[u].f, m = v[u].ind + 2;
    v[u].to_f = v[u].t / m;
    v[f].ex_f += v[u].to_f;
    v[u].ex_f += v[u].t / m + v[u].t % m;
  }
  for (int u = 1; u <= n; u++) {
    int f = v[u].f;
    v[f].s.insert({v[u].ex_f, u});
  }
  for (int i = 1; i <= n; i++) upd(i);
  while (qq--) {
    int c, x, y;
    cin >> c;
    if (c == 3) {
      cout << *gs.begin() << ' ' << *gs.rbegin() << endl;
    } else if (c == 2) {
      cin >> y;
      cout << v[y].ex_f + v[v[y].f].to_f << endl;
    } else {
      cin >> y >> x;
      int xp = v[y].f, fp = v[v[y].f].f, f = v[x].f;
      v[y].f = x;
      del(x);
      v[x].ind++;
      v[x].s.insert({v[y].ex_f, y});
      upd(x);
      v[x].upd_to_f();
      v[x].set_ex_f(v[x].ex_f + v[y].to_f -
                    (v[x].t / (v[x].ind + 1) + v[x].t % (v[x].ind + 1)) +
                    (v[x].t / (v[x].ind + 2) + v[x].t % (v[x].ind + 2)));
      v[f].set_ex_f(v[f].ex_f - v[x].t / (v[x].ind + 1) + v[x].to_f);
      del(xp);
      v[xp].ind--;
      v[xp].s.erase({v[y].ex_f, y});
      upd(xp);
      v[xp].upd_to_f();
      v[xp].set_ex_f(v[xp].ex_f - v[y].to_f -
                     (v[xp].t / (v[xp].ind + 3) + v[xp].t % (v[xp].ind + 3)) +
                     (v[xp].t / (v[xp].ind + 2) + v[xp].t % (v[xp].ind + 2)));
      v[fp].set_ex_f(v[fp].ex_f - v[xp].t / (v[xp].ind + 3) + v[xp].to_f);
    }
  }
  return 0;
}
