#include <bits/stdc++.h>   using namespace std;   const int N = 3e5 + 1;   struct data {     int l, r, sum;   } tree[N << 2], sum_tree[N << 2];   struct node {     int to, next;   } a[N << 1];   int ans1 = 0, ans2 = 0, dp[N], head[N], st[N], ed[N], g[N][25], bx[N], by[N],       bw[N], deep[N];   int n, m, cnt = 0;   vector<int> qx[N];   void add(int x, int y) {     a[++cnt].to = y, a[cnt].next = head[x], head[x] = cnt;     a[++cnt].to = x, a[cnt].next = head[y], head[y] = cnt;   }   void dfs(int u, int fa) {     st[u] = ++cnt;     deep[u] = deep[fa] + 1;     g[u][0] = fa;     for (int i = head[u]; i != -1; i = a[i].next) {       if (a[i].to != fa) dfs(a[i].to, u);     }     ed[u] = cnt;   }   void yyqx() {     for (int i = 1; i < 25; ++i)       for (int j = 1; j <= n; ++j) g[j][i] = g[g[j][i - 1]][i - 1];   }   int GetLCA(int x, int y) {     if (deep[x] > deep[y]) swap(x, y);     for (int i = 24; i >= 0; --i)       if (deep[y] - (1 << i) >= deep[x]) y = g[y][i];     if (x == y) return x;     for (int i = 24; i >= 0; --i)       if (g[x][i] != g[y][i]) x = g[x][i], y = g[y][i];     return g[x][0];   }   void build(int index, int left, int right) {     int mid = (left + right) >> 1;     tree[index].sum = 0, sum_tree[index].sum = 0;     tree[index].l = left, tree[index].r = right;     sum_tree[index].l = left, sum_tree[index].r = right;     if (left == right) return;     build(index * 2, left, mid);     build(index * 2 + 1, mid + 1, right);   }   void change(int index, int left, int right, int d) {     if (left > right) return;     if (tree[index].l >= left && tree[index].r <= right) {       tree[index].sum += d;       return;     }     if (tree[index * 2].r >= left) change(index * 2, left, right, d);     if (tree[index * 2 + 1].l <= right) change(index * 2 + 1, left, right, d);   }   void search(int index, int x) {     ans2 += tree[index].sum;     if (tree[index].l == tree[index].r) return;     if (x <= tree[index * 2].r) search(index * 2, x);     if (x >= tree[index * 2 + 1].l) search(index * 2 + 1, x);   }   void sum_change(int index, int left, int right, int d) {     if (left > right) return;     if (sum_tree[index].l >= left && sum_tree[index].r <= right) {       sum_tree[index].sum += d;       return;     }     if (sum_tree[index * 2].r >= left) sum_change(index * 2, left, right, d);     if (sum_tree[index * 2 + 1].l <= right)       sum_change(index * 2 + 1, left, right, d);   }   void sum_search(int index, int x) {     ans1 += sum_tree[index].sum;     if (sum_tree[index].l == sum_tree[index].r) return;     if (x <= sum_tree[index * 2].r) sum_search(index * 2, x);     if (x >= sum_tree[index * 2 + 1].l) sum_search(index * 2 + 1, x);   }   void work(int u, int fa) {     int sum = 0;     for (int i = head[u]; i != -1; i = a[i].next) {       if (a[i].to != fa) {         work(a[i].to, u);         sum += dp[a[i].to];       }     }     sum_change(1, st[u], ed[u], sum);     dp[u] = sum;     for (int i = 0; i < qx[u].size(); ++i) {       int x = bx[qx[u][i]], y = by[qx[u][i]], w = bw[qx[u][i]];       int val = 0;       ans1 = 0;       sum_search(1, st[x]);       val += ans1;       ans1 = 0;       sum_search(1, st[y]);       val += ans1;       val -= sum;       ans2 = 0;       search(1, st[x]);       val -= ans2;       ans2 = 0;       search(1, st[y]);       val -= ans2;       dp[u] = max(dp[u], val + w);     }     ans1 = 0, ans2 = 0;     change(1, st[u], ed[u], dp[u]);   }   int main() {     int x, y, w;     scanf( %d%d , &n, &m);     memset(head, -1, sizeof(head));     for (int i = 1; i < n; ++i) {       scanf( %d , &x);       add(x, i + 1);     }     cnt = 0;     dfs(1, 0);     yyqx();     for (int i = 1; i <= m; ++i) {       scanf( %d%d%d , &x, &y, &w);       bx[i] = x, by[i] = y, bw[i] = w;       qx[GetLCA(x, y)].push_back(i);     }     build(1, 1, n);     work(1, 0);     printf( %d n , dp[1]);     return 0;   }