func_code_string: #include <bits/stdc++.h>   using namespace std;   const int N = 2e5 + 50, B = 1111;   const long double inf = 5e18;   const long double eps = 1e-12;   int n, q, a[N], b[N], f[N], blo[N], sq, num, ll[N], rr[N], dfn[N], dfm[N], clk,       idfn[N];   vector<int> v[N];   int read() {     int x = 0, c, f = 1;     while (!isdigit(c = getchar())) c ==  -  ? f = -1 : 0;     while (isdigit(c)) x = x * 10 + c - 48, c = getchar();     return x * f;   }   void dfs(int x) {     dfn[x] = ++clk;     idfn[clk] = x;     for (int i = 0; i < v[x].size(); i++) dfs(v[x][i]);     dfm[x] = clk;   }   long double k(long long y, int x) {     return x ? 1.0 * y / x : y > 0 ? inf : -inf;   }   void cmax(long long &x, long long y) { y > x ? x = y : 0; }   bool cmp(int x, int y) { return b[idfn[x]] < b[idfn[y]]; }   struct node {     int a[N], b[N], t[N], st[B][B], tp[B];     long long y[N];     vector<int> v[B];     void build(int i) {       int *Q = st[i], &R = tp[i];       R = 0;       for (int j = 0; j < v[i].size(); j++) {         int x = v[i][j];         assert(!j || b[x] >= b[v[i][j - 1]]);         while (R > 1 && k(y[Q[R]] - y[Q[R - 1]], b[Q[R]] - b[Q[R - 1]]) -                                 k(y[x] - y[Q[R]], b[x] - b[Q[R]]) <                             eps)           R--;         Q[++R] = x;       }     }     void init() {       for (int i = 1; i <= num; i++) {         for (int j = ll[i]; j <= rr[i]; j++)           v[i].push_back(j), y[j] = 1ll * a[j] * b[j];         sort(v[i].begin(), v[i].end(), cmp);         build(i);       }     }     void change(int l, int r, int x) {       for (int i = l; i <= min(r, rr[blo[l]]); i++)         a[i] -= x, y[i] = 1ll * a[i] * b[i];       build(blo[l]);       if (blo[l] != blo[r]) {         for (int i = ll[blo[r]]; i <= r; i++) a[i] -= x, y[i] = 1ll * a[i] * b[i];         build(blo[r]);       }       for (int i = blo[l] + 1; i < blo[r]; i++) t[i] += x;     }     long long query(int l, int r) {       long long ret = 0;       for (int i = l; i <= min(r, rr[blo[l]]); i++)         cmax(ret, 1ll * (a[i] - t[blo[l]]) * b[i]);       if (blo[l] != blo[r])         for (int i = ll[blo[r]]; i <= r; i++)           cmax(ret, 1ll * (a[i] - t[blo[r]]) * b[i]);       for (int i = blo[l] + 1; i < blo[r]; i++) {         int *Q = st[i], &R = tp[i];         while (R > 1 &&                k(y[Q[R]] - y[Q[R - 1]], b[Q[R]] - b[Q[R - 1]]) < t[i] + eps)           R--;         cmax(ret, 1ll * (a[Q[R]] - t[i]) * b[Q[R]]);       }       return ret;     }   } F, G;   int main() {     scanf( %d%d , &n, &q);     sq = max((int)sqrt(n / 6), 1);     for (int i = 2; i <= n; i++) v[f[i] = read()].push_back(i);     dfs(1);     for (int i = 1; i <= n; i++) a[i] = read() + a[f[i]];     for (int i = 1; i <= n; i++) b[i] = read() + b[f[i]];     for (int i = 1; i <= n; i++) blo[i] = (i - 1) / sq + 1;     num = blo[n];     for (int i = 1; i <= num; i++) ll[i] = (i - 1) * sq + 1, rr[i] = i * sq;     rr[num] = n;     for (int i = 1; i <= n; i++)       F.a[i] = G.a[i] = -a[idfn[i]], F.b[i] = b[idfn[i]], G.b[i] = -b[idfn[i]];     F.init();     for (int i = 1; i <= n; i++) b[i] = -b[i];     G.init();     for (int i = 1, op, x, y; i <= q; i++) {       op = read();       x = read();       if (op == 1)         y = read(), F.change(dfn[x], dfm[x], y), G.change(dfn[x], dfm[x], y);       else         cout << max(F.query(dfn[x], dfm[x]), G.query(dfn[x], dfm[x])) << endl;     }     return 0;   }   