#include <bits/stdc++.h>
using namespace std;
const long long MAXN = 1e5 + 10;
const long long INF = 2e9;
const double eps = 1e-6;
const double PI = acos(-1);
long long n, m, q;
long long sum[MAXN], cnt[MAXN], t[MAXN], fa[MAXN];
multiset<long long> s[MAXN], S;
template <typename T>
inline bool read(T &a) {
  a = 0;
  char c = getchar();
  long long f = 1;
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    a = a * 10 + (c ^ 48);
    c = getchar();
  }
  return a *= f, true;
}
template <typename A, typename... B>
inline bool read(A &x, B &...y) {
  return read(x) && read(y...);
}
long long cme(long long x) { return t[x] - t[x] / (cnt[x] + 2) * (cnt[x] + 1); }
long long cson(long long x) { return t[x] / (cnt[x] + 2); }
void del(long long x) {
  if (!s[x].size()) return;
  S.erase(S.find(*s[x].begin() + cson(x)));
  S.erase(S.find(*(--s[x].end()) + cson(x)));
}
void add(long long x) {
  if (!s[x].size()) return;
  S.insert(*s[x].begin() + cson(x));
  S.insert(*(--s[x].end()) + cson(x));
}
void update(long long x, long long y) {
  static vector<long long> tmp, idx, idx2;
  tmp.clear(), idx.clear(), idx2.clear();
  tmp.push_back(x), tmp.push_back(y), tmp.push_back(fa[x]),
      tmp.push_back(fa[fa[x]]), tmp.push_back(fa[y]);
  for (auto x : tmp)
    if (x) idx.push_back(x);
  idx2 = idx;
  for (auto x : idx)
    if (fa[x]) idx2.push_back(fa[x]);
  sort(idx.begin(), idx.end()), sort(idx2.begin(), idx2.end());
  idx.erase(unique(idx.begin(), idx.end()), idx.end());
  idx2.erase(unique(idx2.begin(), idx2.end()), idx2.end());
  for (auto x : idx2) del(x);
  for (auto x : idx) s[fa[x]].erase(s[fa[x]].find(sum[x]));
  for (auto x : idx) {
    sum[x] -= cme(x);
    for (auto y : idx)
      if (fa[y] == x) sum[x] -= cson(y);
  }
  cnt[fa[x]]--;
  fa[x] = y;
  cnt[fa[x]]++;
  for (auto x : idx) {
    sum[x] += cme(x);
    for (auto y : idx)
      if (fa[y] == x) sum[x] += cson(y);
  }
  for (auto x : idx) s[fa[x]].insert(sum[x]);
  for (auto x : idx2) add(x);
}
void solve() {
  long long opt, x, y;
  read(opt);
  if (opt == 1) read(x), read(y), update(x, y);
  if (opt == 2) read(x), printf("%lld\n", sum[x] + cson(fa[x]));
  if (opt == 3) printf("%lld %lld\n", *S.begin(), *(--S.end()));
}
signed main() {
  read(n), read(q);
  for (long long i = 1; i <= n; ++i) read(t[i]);
  for (long long i = 1; i <= n; ++i) read(fa[i]), cnt[fa[i]]++;
  for (long long i = 1; i <= n; ++i) sum[i] += cme(i), sum[fa[i]] += cson(i);
  for (long long i = 1; i <= n; ++i) s[fa[i]].insert(sum[i]);
  for (long long i = 1; i <= n; ++i) add(i);
  while (q--) solve();
  return 0;
}
