#include <bits/stdc++.h>
using namespace std;
inline int ReadInt() {
  static int n, ch;
  n = 0, ch = getchar();
  while (!isdigit(ch)) ch = getchar();
  while (isdigit(ch)) n = (n << 1) + (n << 3) + ch - '0', ch = getchar();
  return n;
}
inline long long ReadLL() {
  static long long n;
  static int ch;
  n = 0, ch = getchar();
  while (!isdigit(ch)) ch = getchar();
  while (isdigit(ch)) n = (n << 1) + (n << 3) + ch - '0', ch = getchar();
  return n;
}
const int maxn = 100000 + 3;
const long long INF = 1LL << 60;
multiset<long long> opt_set, sets[maxn];
int n, q, fa[maxn], s[maxn];
long long t[maxn], val[maxn];
inline long long cal(int u) { return t[u] / (s[u] + 2); }
bool in_opt[maxn], in_val[maxn];
inline void erase_val(int a) {
  int b = fa[a];
  if (in_val[a]) {
    sets[b].erase(sets[b].find(val[a]));
    in_val[a] = false;
  }
}
inline void insert_val(int a) {
  int b = fa[a];
  if (!in_val[a]) {
    sets[b].insert(val[a]);
    in_val[a] = true;
  }
}
inline void erase_opt(int a) {
  if (in_opt[a]) {
    long long v = cal(a);
    opt_set.erase(opt_set.find(*sets[a].begin() + v));
    opt_set.erase(opt_set.find(*sets[a].rbegin() + v));
    in_opt[a] = false;
  }
}
inline void insert_opt(int a) {
  if (!in_opt[a] && sets[a].size()) {
    long long v = cal(a);
    opt_set.insert(*sets[a].begin() + v);
    opt_set.insert(*sets[a].rbegin() + v);
    in_opt[a] = true;
  }
}
void modify(int a, int c) {
  int b = fa[a];
  erase_opt(b), erase_opt(c), erase_opt(fa[b]), erase_opt(fa[c]),
      erase_opt(fa[fa[b]]), erase_opt(fa[fa[c]]);
  erase_val(a), erase_val(b), erase_val(c), erase_val(fa[b]), erase_val(fa[c]);
  fa[a] = c;
  long long va_other = cal(a);
  long long vb_other = cal(b);
  val[b] -= va_other;
  val[b] -= t[b] - (s[b] + 1) * vb_other;
  val[fa[b]] -= vb_other;
  s[b]--;
  vb_other = t[b] / (s[b] + 2);
  val[b] += t[b] - (s[b] + 1) * vb_other;
  val[fa[b]] += vb_other;
  long long vc_other = cal(c);
  val[c] += va_other;
  val[c] -= t[c] - (s[c] + 1) * vc_other;
  val[fa[c]] -= vc_other;
  s[c]++;
  vc_other = t[c] / (s[c] + 2);
  val[c] += t[c] - (s[c] + 1) * vc_other;
  val[fa[c]] += vc_other;
  insert_val(a), insert_val(b), insert_val(c), insert_val(fa[b]),
      insert_val(fa[c]);
  insert_opt(b), insert_opt(c), insert_opt(fa[b]), insert_opt(fa[c]),
      insert_opt(fa[fa[b]]), insert_opt(fa[fa[c]]);
}
int main() {
  n = ReadInt(), q = ReadInt();
  for (int i = 0; i < n; ++i) t[i] = ReadLL();
  for (int i = 0; i < n; ++i) s[fa[i] = ReadInt() - 1]++;
  for (int i = 0; i < n; ++i) {
    long long v = cal(i);
    val[fa[i]] += v, val[i] += t[i] - (s[i] + 1) * v;
  }
  memset(in_opt, 0, sizeof(bool) * n);
  memset(in_val, 0, sizeof(bool) * n);
  for (int i = 0; i < n; ++i) insert_val(i);
  for (int i = 0; i < n; ++i) insert_opt(i);
  while (q--) {
    int type = ReadInt();
    if (type == 1) {
      int u = ReadInt() - 1, v = ReadInt() - 1;
      modify(u, v);
    } else if (type == 2) {
      int u = ReadInt() - 1;
      printf("%I64d\n", val[u] + cal(fa[u]));
    } else if (type == 3) {
      printf("%I64d %I64d\n", *opt_set.begin(), *opt_set.rbegin());
    } else
      assert(false);
  }
  return 0;
}
