#include <bits/stdc++.h>   using namespace std;   struct Fenwick {     int n;     long long tree[200002];     void init(int _n) {       n = _n;       fill(tree + 1, tree + n + 1, 0LL);     }     void upd(int x, long long val) {       while (x <= n) {         tree[x] += val;         x += x & -x;       }     }     long long sum(int x) {       long long ret = 0;       while (x) {         ret += tree[x];         x -= x & -x;       }       return ret;     }   } tree;   struct Query {     int u, v;     long long cost;     Query() {}     Query(int u, int v, long long cost) : u(u), v(v), cost(cost) {}   };   int n, m;   int par[200002];   vector<int> child[200002];   int depth[200002], LCADB[200002][20];   long long DP[200002];   int sz[200002];   vector<Query> queryVec[200002];   int in[200002], top[200002], idx[200002];   long long DPSum[200002];   void makeTree(int x) {     sz[x] = 1;     for (auto &y : child[x]) {       depth[y] = depth[x] + 1;       makeTree(y);       sz[x] += sz[y];       if (sz[y] > sz[child[x][0]]) swap(child[x][0], y);     }   }   int in_cnt;   void dfs_hld(int x) {     in[x] = ++in_cnt;     idx[in[x]] = x;     for (auto y : child[x]) {       top[y] = (child[x][0] == y) ? top[x] : y;       dfs_hld(y);     }   }   int getLCA(int x, int y) {     if (depth[x] < depth[y]) swap(x, y);     for (int d = 0; d < 20; d++)       if ((depth[x] - depth[y]) & (1 << d)) x = LCADB[x][d];     if (x == y) return x;     for (int d = 19; d >= 0; d--)       if (LCADB[x][d] != LCADB[y][d]) x = LCADB[x][d], y = LCADB[y][d];     return par[x];   }   int kth_parent(int x, int k) {     for (int d = 0; d < 20; d++) {       if ((k >> d) & 1) x = LCADB[x][d];     }     return x;   }   long long pathQuery(int x, int topD) {     long long ret = 0;     while (depth[x] >= topD) {       int tp = in[top[x]];       int tStart = max(topD, depth[top[x]]) - depth[top[x]] + tp;       int tEnd = depth[x] - depth[top[x]] + tp;       ret += tree.sum(tEnd) - tree.sum(tStart - 1);       x = par[top[x]];     }     return ret;   }   void dfs(int x) {     long long dpSum = 0;     for (auto y : child[x]) {       dfs(y);       dpSum += DP[y];     }     DPSum[x] = DP[x] = dpSum;     for (auto y : child[x]) {       tree.upd(in[y], dpSum - DP[y]);     }     for (auto query : queryVec[x]) {       int tx = query.u, ty = query.v;       long long tv = query.cost;       assert(depth[tx] <= depth[ty]);       long long val;       if (tx == x) {         val = dpSum + tv;         val -= DP[kth_parent(ty, depth[ty] - depth[tx] - 1)];         val += pathQuery(ty, depth[x] + 2);         val += DPSum[ty];       } else {         val = dpSum + tv;         val -= DP[kth_parent(tx, depth[tx] - depth[x] - 1)];         val -= DP[kth_parent(ty, depth[ty] - depth[x] - 1)];         val += pathQuery(tx, depth[x] + 2);         val += pathQuery(ty, depth[x] + 2);         val += DPSum[tx];         val += DPSum[ty];       }       DP[x] = max(DP[x], val);     }   }   int main() {     scanf( %d %d , &n, &m);     for (int i = 2; i <= n; i++) {       scanf( %d , &par[i]);       LCADB[i][0] = par[i];       child[par[i]].push_back(i);     }     makeTree(1);     top[1] = 1;     dfs_hld(1);     for (int d = 1; d < 20; d++)       for (int i = 1; i <= n; i++) LCADB[i][d] = LCADB[LCADB[i][d - 1]][d - 1];     for (int i = 1; i <= m; i++) {       Query tmp;       scanf( %d %d %lld , &tmp.u, &tmp.v, &tmp.cost);       if (depth[tmp.u] > depth[tmp.v]) swap(tmp.u, tmp.v);       int z = getLCA(tmp.u, tmp.v);       queryVec[z].push_back(tmp);     }     tree.init(n);     dfs(1);     printf( %lld , DP[1]);   }