#include <bits/stdc++.h>
const int N = 200005;
const int MX = 20;
using namespace std;
int fa[N][21], dl[N], dr[N], f[N], dep[N];
int edge[N], nxt[N], lst[N], t = 0;
int tot = 0, n, m;
vector<int> q[N];
struct nn {
  int u, v, w;
} a[N];
void add(int x, int y) {
  edge[++t] = y;
  nxt[t] = lst[x];
  lst[x] = t;
}
void search(int x) {
  dep[x] = dep[fa[x][0]] + 1;
  tot++;
  dl[x] = dr[x] = tot;
  for (int r = lst[x]; r; r = nxt[r]) {
    if (edge[r] == fa[x][0]) continue;
    search(edge[r]);
    dr[x] = max(dr[x], dr[edge[r]]);
  }
}
int LCA(int x, int y) {
  if (dep[x] < dep[y]) swap(x, y);
  int de = dep[x] - dep[y];
  for (int i = 20; i >= 0; i--)
    if (de & (1 << i)) x = fa[x][i];
  if (x == y) return x;
  for (int i = 20; i >= 0; i--)
    if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
  return fa[x][0];
}
struct tree {
  struct node {
    int tag, tot, lx, rx, sz;
  } tr[N << 1];
  void chk(int x) {
    int l = tr[x].lx, r = tr[x].rx;
    tr[x].tot = tr[l].tot + tr[r].tot;
    tr[x].sz = tr[l].sz + tr[r].sz;
  }
  void pushd(int x) {
    int l = tr[x].lx, r = tr[x].rx;
    if (tr[x].tag) {
      tr[l].tot += tr[l].sz * tr[x].tag;
      tr[r].tot += tr[r].sz * tr[x].tag;
      tr[l].tag += tr[x].tag;
      tr[r].tag += tr[x].tag;
      tr[x].tag = 0;
    }
  }
  void insert(int x, int l, int r, int l1, int r1, int yh) {
    if (l == l1 && r == r1) {
      tr[x].tot += tr[x].sz * yh;
      tr[x].tag += yh;
      return;
    }
    pushd(x);
    int mid = (l + r) >> 1;
    if (l1 > mid)
      insert(tr[x].rx, mid + 1, r, l1, r1, yh);
    else if (r1 <= mid)
      insert(tr[x].lx, l, mid, l1, r1, yh);
    else {
      insert(tr[x].lx, l, mid, l1, mid, yh);
      insert(tr[x].rx, mid + 1, r, mid + 1, r1, yh);
    }
    chk(x);
  }
  int find(int x, int l, int r, int pos) {
    if (l == r) return tr[x].tot;
    pushd(x);
    int mid = (l + r) >> 1;
    if (pos > mid)
      return find(tr[x].rx, mid + 1, r, pos);
    else
      return find(tr[x].lx, l, mid, pos);
  }
  void build(int x, int l, int r) {
    if (l == r) {
      tr[x].sz = 1;
      tr[x].tot = tr[x].tag = 0;
      return;
    }
    int mid = (l + r) >> 1;
    tr[x].lx = x + 1;
    tr[x].rx = x + (mid - l + 1) * 2;
    build(tr[x].lx, l, mid);
    build(tr[x].rx, mid + 1, r);
    chk(x);
  }
};
tree sub, dp;
void getans(int x) {
  int sum = 0;
  for (int r = lst[x]; r; r = nxt[r]) {
    if (edge[r] == fa[x][0]) continue;
    getans(edge[r]);
    sum += f[edge[r]];
  }
  f[x] = sum;
  sub.insert(1, 1, n, dl[x], dr[x], sum);
  int ss = q[x].size();
  for (int i = 0; i < ss; i++) {
    int nx = a[q[x][i]].u, ny = a[q[x][i]].v, nz = a[q[x][i]].w;
    int num = 0;
    num += sub.find(1, 1, n, dl[nx]);
    num += sub.find(1, 1, n, dl[ny]);
    num -= sum;
    num -= dp.find(1, 1, n, dl[nx]);
    num -= dp.find(1, 1, n, dl[ny]);
    if (num + nz > f[x]) {
      f[x] = num + nz;
    }
  }
  dp.insert(1, 1, n, dl[x], dr[x], f[x]);
}
int main() {
  scanf("%d%d", &n, &m);
  fa[1][0] = 0;
  for (int i = 2; i <= n; i++) scanf("%d", &fa[i][0]), add(fa[i][0], i);
  for (int j = 1; j <= MX; j++)
    for (int i = 1; i <= n; i++) fa[i][j] = fa[fa[i][j - 1]][j - 1];
  search(1);
  sub.build(1, 1, n);
  dp.build(1, 1, n);
  for (int i = 1; i <= m; i++) {
    scanf("%d%d%d", &a[i].u, &a[i].v, &a[i].w);
    q[LCA(a[i].u, a[i].v)].push_back(i);
  }
  getans(1);
  printf("%d\n", f[1]);
  return 0;
}
