#include <bits/stdc++.h>   using namespace std;   inline long long read() {     long long s = 0, w = 1;     char ch = getchar();     while (ch <  0  || ch >  9 ) {       if (ch ==  - ) w = -1;       ch = getchar();     }     while ( 0  <= ch && ch <=  9 )       s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();     return s * w;   }   int n, q;   long long A[300010], B[300010], C[300010], D[300010], E[300010];   multiset<long long> S_Max, S_Min;   multiset<long long> S[300010];   int main() {     n = read(), q = read();     for (register int i = 1; i <= n; i++) B[i] = read();     for (register int i = 1; i <= n; i++) A[i] = read(), D[i] += 2, D[A[i]]++;     for (register int i = 1; i <= n; i++) E[i] = B[i] / D[i];     for (register int i = 1; i <= n; i++) C[A[i]] += E[i];     for (register int i = 1; i <= n; i++)       S[A[i]].insert(B[i] - D[i] * E[i] + E[i] + C[i]);     for (register int i = 1; i <= n; i++)       if (!S[i].empty()) {         S_Max.insert(*S[i].rbegin() + E[i]);         S_Min.insert(*S[i].begin() + E[i]);       }     while (q--) {       int opt = read();       if (opt == 1) {         int x = read(), y = read(), fa = A[x];         S_Max.erase(S_Max.find(*S[fa].rbegin() + E[fa]));         S_Min.erase(S_Min.find(*S[fa].begin() + E[fa]));         S[fa].erase(S[fa].find(B[x] - D[x] * E[x] + E[x] + C[x]));         S_Max.erase(S_Max.find(*S[A[fa]].rbegin() + E[A[fa]]));         S_Min.erase(S_Min.find(*S[A[fa]].begin() + E[A[fa]]));         S[A[fa]].erase(S[A[fa]].find(B[fa] - D[fa] * E[fa] + E[fa] + C[fa]));         S_Max.erase(S_Max.find(*S[A[A[fa]]].rbegin() + E[A[A[fa]]]));         S_Min.erase(S_Min.find(*S[A[A[fa]]].begin() + E[A[A[fa]]]));         S[A[A[fa]]].erase(S[A[A[fa]]].find(B[A[fa]] - D[A[fa]] * E[A[fa]] +                                            E[A[fa]] + C[A[fa]]));         C[A[fa]] -= E[fa];         D[fa]--, E[fa] = B[fa] / D[fa], C[fa] -= E[x];         C[A[fa]] += E[fa];         S[A[A[fa]]].insert(B[A[fa]] - D[A[fa]] * E[A[fa]] + E[A[fa]] + C[A[fa]]);         S_Max.insert(*S[A[A[fa]]].rbegin() + E[A[A[fa]]]);         S_Min.insert(*S[A[A[fa]]].begin() + E[A[A[fa]]]);         S[A[fa]].insert(B[fa] - D[fa] * E[fa] + E[fa] + C[fa]);         S_Max.insert(*S[A[fa]].rbegin() + E[A[fa]]);         S_Min.insert(*S[A[fa]].begin() + E[A[fa]]);         if (!S[fa].empty()) {           S_Max.insert(*S[fa].rbegin() + E[fa]);           S_Min.insert(*S[fa].begin() + E[fa]);         }         if (!S[y].empty()) {           S_Max.erase(S_Max.find(*S[y].rbegin() + E[y]));           S_Min.erase(S_Min.find(*S[y].begin() + E[y]));         }         S[y].insert(B[x] - D[x] * E[x] + E[x] + C[x]);         S_Max.erase(S_Max.find(*S[A[y]].rbegin() + E[A[y]]));         S_Min.erase(S_Min.find(*S[A[y]].begin() + E[A[y]]));         S[A[y]].erase(S[A[y]].find(B[y] - D[y] * E[y] + E[y] + C[y]));         S_Max.erase(S_Max.find(*S[A[A[y]]].rbegin() + E[A[A[y]]]));         S_Min.erase(S_Min.find(*S[A[A[y]]].begin() + E[A[A[y]]]));         S[A[A[y]]].erase(             S[A[A[y]]].find(B[A[y]] - D[A[y]] * E[A[y]] + E[A[y]] + C[A[y]]));         C[A[y]] -= E[y];         D[y]++, E[y] = B[y] / D[y], C[y] += E[x];         C[A[y]] += E[y];         S[A[A[y]]].insert(B[A[y]] - D[A[y]] * E[A[y]] + E[A[y]] + C[A[y]]);         S_Max.insert(*S[A[A[y]]].rbegin() + E[A[A[y]]]);         S_Min.insert(*S[A[A[y]]].begin() + E[A[A[y]]]);         S[A[y]].insert(B[y] - D[y] * E[y] + E[y] + C[y]);         S_Max.insert(*S[A[y]].rbegin() + E[A[y]]);         S_Min.insert(*S[A[y]].begin() + E[A[y]]);         S_Max.insert(*S[y].rbegin() + E[y]);         S_Min.insert(*S[y].begin() + E[y]);         A[x] = y;       } else if (opt == 2) {         int x = read();         printf( %lld n , B[x] - D[x] * E[x] + E[x] + C[x] + E[A[x]]);       } else         printf( %lld %lld n , *S_Min.begin(), *S_Max.rbegin());     }     return 0;   }