#include <bits/stdc++.h>
using namespace std;
const int MX = 100005;
template <typename T>
void cmin(T &x, const T &y) {
  if (y < x) x = y;
}
template <typename T>
void cmax(T &x, const T &y) {
  if (y > x) x = y;
}
template <typename T>
void read(T &x) {
  x = 0;
  char c = getchar();
  bool f = 0;
  while (!isdigit(c) && c != '-') c = getchar();
  if (c == '-') f = 1, c = getchar();
  while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
  if (f) x = -x;
}
int n, q;
int fa[MX];
int deg[MX];
long long mass[MX];
long long self_son[MX];
long long for_others(int i) { return mass[i] / (deg[i] + 1); }
long long for_self(int i) { return mass[i] - for_others(i) * deg[i]; }
struct SONS {
  struct cmp {
    bool operator()(int a, int b) const {
      if (self_son[a] != self_son[b])
        return self_son[a] < self_son[b];
      else
        return a < b;
    }
  };
  set<int, cmp> s;
  void most(vector<int> &ret) {
    if (!s.size())
      return;
    else if (s.size() == 1)
      ret.push_back(*s.begin());
    else
      ret.push_back(*s.begin()), ret.push_back(*s.rbegin());
  }
} son[MX];
multiset<long long> global;
void input() {
  read(n), read(q);
  for (int i = 1; i <= n; i++) read(mass[i]);
  for (int i = 1; i <= n; i++) read(fa[i]), deg[i]++, deg[fa[i]]++;
}
long long get_sum(int x) { return self_son[x] + for_others(fa[x]); }
void build() {
  for (int i = 1; i <= n; i++) {
    self_son[i] += for_self(i);
    self_son[fa[i]] += for_others(i);
  }
  for (int i = 1; i <= n; i++) son[fa[i]].s.insert(i);
  for (int i = 1; i <= n; i++) {
    vector<int> most;
    son[i].most(most);
    for (auto j : most) global.insert(get_sum(j));
  }
}
void work() {
  for (int i = 1; i <= q; i++) {
    int op;
    read(op);
    if (op == 1) {
      vector<int> most;
      int a, b, c;
      read(a), read(c), b = fa[a];
      most.clear();
      son[b].most(most);
      son[c].most(most);
      son[fa[b]].most(most);
      son[fa[c]].most(most);
      son[fa[fa[b]]].most(most);
      son[fa[fa[c]]].most(most);
      sort(most.begin(), most.end());
      most.erase(unique(most.begin(), most.end()), most.end());
      for (auto x : most) global.erase(global.find(get_sum(x)));
      son[b].s.erase(a);
      son[fa[b]].s.erase(b);
      son[fa[c]].s.erase(c);
      son[fa[fa[b]]].s.erase(fa[b]);
      son[fa[fa[c]]].s.erase(fa[c]);
      self_son[fa[b]] -= for_others(b);
      self_son[fa[c]] -= for_others(c);
      self_son[b] -= for_others(a);
      self_son[b] -= for_self(b);
      self_son[c] -= for_self(c);
      deg[b]--;
      fa[a] = c;
      deg[c]++;
      self_son[c] += for_self(c);
      self_son[b] += for_self(b);
      self_son[c] += for_others(a);
      self_son[fa[b]] += for_others(b);
      self_son[fa[c]] += for_others(c);
      son[fa[fa[b]]].s.insert(fa[b]);
      son[fa[fa[c]]].s.insert(fa[c]);
      son[fa[b]].s.insert(b);
      son[fa[c]].s.insert(c);
      son[c].s.insert(a);
      most.clear();
      son[b].most(most);
      son[c].most(most);
      son[fa[b]].most(most);
      son[fa[c]].most(most);
      son[fa[fa[b]]].most(most);
      son[fa[fa[c]]].most(most);
      sort(most.begin(), most.end());
      most.erase(unique(most.begin(), most.end()), most.end());
      for (auto x : most) global.insert(get_sum(x));
    } else if (op == 2) {
      int x;
      read(x);
      printf("%lld\n", get_sum(x));
    } else {
      printf("%lld %lld\n", *global.begin(), *global.rbegin());
    }
  }
}
int main() {
  input();
  build();
  work();
  return 0;
}
