#include <bits/stdc++.h>
using namespace std;
int n, q;
const long long INF = 1e18;
struct M {
  priority_queue<long long> qmax, delmax;
  priority_queue<long long, vector<long long>, greater<long long> > qmin,
      delmin;
  void ins(long long x) {
    qmax.push(x);
    qmin.push(x);
    return;
  }
  void del(long long x) {
    delmax.push(x);
    delmin.push(x);
    return;
  }
  long long query_max() {
    while (!delmax.empty() && delmax.top() == qmax.top()) {
      qmax.pop();
      delmax.pop();
    }
    if (!qmax.empty()) return qmax.top();
    return -INF;
  }
  long long query_min() {
    while (!delmin.empty() && delmin.top() == qmin.top()) {
      qmin.pop();
      delmin.pop();
    }
    if (!qmin.empty()) return qmin.top();
    return INF;
  }
} Globalmax, Globalmin;
struct Magic {
  M S;
  int k, to;
  long long sum, t;
  long long addval() { return t / k; }
  long long val() { return sum + addval() + t % k; }
  void fix() {
    Globalmax.ins(S.query_max() + addval());
    Globalmin.ins(S.query_min() + addval());
    return;
  }
  void ifix() {
    Globalmax.del(S.query_max() + addval());
    Globalmin.del(S.query_min() + addval());
    return;
  }
  void ins(long long x) {
    ifix();
    S.ins(x);
    fix();
    return;
  }
  void del(long long x) {
    ifix();
    S.del(x);
    fix();
    return;
  }
} p[100010];
void add_sum(int u, long long x) {
  p[p[u].to].del(p[u].val());
  p[u].sum += x;
  p[p[u].to].ins(p[u].val());
  return;
}
void add_t(int u, int x) {
  p[u].ifix();
  p[p[u].to].del(p[u].val());
  long long o = p[u].addval();
  p[u].k += x;
  o = p[u].addval() - o;
  add_sum(p[u].to, o);
  p[u].fix();
  p[p[u].to].ins(p[u].val());
  return;
}
void change(int o, int v) {
  int u = p[o].to;
  p[u].del(p[o].val());
  add_sum(u, -p[o].addval());
  add_t(u, -1);
  p[o].to = v;
  p[v].ins(p[o].val());
  add_sum(v, p[o].addval());
  add_t(v, 1);
  return;
}
int main() {
  scanf("%d %d", &n, &q);
  for (int i = 1; i <= n; i++) scanf("%I64d", &p[i].t), p[i].k = 2;
  for (int i = 1; i <= n; i++) {
    scanf("%d", &p[i].to);
    p[p[i].to].k++;
  }
  for (int i = 1; i <= n; i++) p[p[i].to].sum += p[i].addval();
  for (int i = 1; i <= n; i++) p[p[i].to].ins(p[i].val());
  for (int i = 1; i <= q; i++) {
    int op;
    scanf("%d", &op);
    if (op == 1) {
      int x, y;
      scanf("%d %d", &x, &y);
      change(x, y);
    } else if (op == 2) {
      int x;
      scanf("%d", &x);
      printf("%I64d\n", p[x].val() + p[p[x].to].addval());
    } else
      printf("%I64d %I64d\n", Globalmin.query_min(), Globalmax.query_max());
  }
  return 0;
}
