#include <bits/stdc++.h>
using namespace std;
multiset<long long> S;
int n, q, p[1000005];
long long t[1000005], ans[1000005];
struct cmp {
  bool operator()(int a, int b) {
    if (ans[a] != ans[b]) return ans[a] < ans[b];
    return a < b;
  }
};
struct node {
  int num;
  set<int, cmp> s;
  vector<long long> get() {
    vector<long long> v;
    if (!s.empty()) v.push_back(ans[*s.begin()]);
    if (s.size() >= 2) {
      auto it = s.end();
      it--;
      v.push_back(ans[*it]);
    }
    return v;
  }
  void insert(int a) { s.insert(a); }
  void erase(int a) { s.erase(a); }
} f[1000005];
long long other(int a) { return t[a] / (2 + f[a].num); }
long long self(int a) { return t[a] - (1 + f[a].num) * other(a); }
int main() {
  scanf("%d%d", &n, &q);
  for (int i = 1; i <= n; i++) scanf("%I64d", &t[i]);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &p[i]);
    f[p[i]].num++, f[p[i]].insert(i);
  }
  for (int i = 1; i <= n; i++) {
    f[p[i]].erase(i);
    ans[i] = self(i);
    for (int x : f[i].s) ans[i] += other(x);
    f[p[i]].insert(i);
  }
  for (int i = 1; i <= n; i++) {
    vector<long long> V = f[i].get();
    for (long long v : V) S.insert(v + other(i));
  }
  while (q--) {
    int op;
    scanf("%d", &op);
    if (op == 1) {
      int a, b;
      scanf("%d%d", &a, &b);
      set<int> update = set<int>{a, p[a], p[p[a]], b, p[b]};
      set<int> update1 = update;
      for (int x : update) update1.insert(p[x]);
      for (int x : update1) {
        vector<long long> V = f[x].get();
        for (long long v : V) {
          auto it = S.find(v + other(x));
          if (it != S.end()) S.erase(it);
        }
      }
      for (int x : update) f[p[x]].erase(x);
      for (int state = -1; state <= 1; state += 2) {
        for (int x : update) {
          ans[x] += state * self(x);
          for (int y : update)
            if (p[y] == x) ans[x] += state * other(y);
        }
        if (state == -1) f[p[a]].num--, p[a] = b, f[b].num++;
      }
      for (int x : update) f[p[x]].insert(x);
      for (int x : update1) {
        vector<long long> V = f[x].get();
        for (long long v : V) S.insert(v + other(x));
      }
    } else if (op == 2) {
      int a;
      scanf("%d", &a);
      printf("%I64d\n", ans[a] + other(p[a]));
    } else {
      printf("%I64d ", *S.begin());
      auto it = S.end();
      it--;
      printf("%I64d\n", *it);
    }
  }
  return 0;
}
