#include <bits/stdc++.h>
using namespace std;
struct Edge {
  int a, b;
  int cost;
  void read() {
    scanf("%d%d%d", &a, &b, &cost);
    --a;
    --b;
  }
};
int n, m;
vector<vector<int>> g;
vector<Edge> es;
bool read() {
  if (scanf("%d%d", &n, &m) < 2) {
    return 0;
  }
  g.clear();
  g.resize(n);
  for (int i = 1; i < n; ++i) {
    int par;
    scanf("%d", &par);
    --par;
    g[par].push_back(i);
  }
  es.resize(m);
  for (int i = 0; i < int(m); ++i) {
    es[i].read();
  }
  return 1;
}
struct FenwTree {
  vector<int> t;
  FenwTree(int n = 0) { t.assign(n, 0); }
  int get(int r) {
    int s = 0;
    for (int i = r; i >= 0; i &= i + 1, --i) {
      s += t[i];
    }
    return s;
  }
  int get(int l, int r) { return get(r) - get(l - 1); }
  void inc(int pos, int v) {
    for (int i = pos; i < ((int)(t).size()); i |= i + 1) {
      t[i] += v;
    }
  }
};
int LOG;
vector<vector<int>> par;
vector<int> tin;
vector<int> tout;
int timer;
vector<vector<Edge>> es_node;
vector<int> dp;
vector<int> sum_dp;
vector<int> order;
FenwTree fenwTree;
bool upper(int a, int b) { return tin[a] <= tin[b] && tout[b] <= tout[a]; }
int lca(int a, int b) {
  if (upper(a, b)) {
    return a;
  }
  if (upper(b, a)) {
    return b;
  }
  for (int l = int(LOG) - 1; l >= 0; --l) {
    if (!upper(par[b][l], a)) {
      b = par[b][l];
    }
  }
  return par[b][0];
}
void set_func(int v, int f) {
  fenwTree.inc(tin[v], f);
  fenwTree.inc(tout[v], -f);
}
int sum_func(int a, int b) {
  assert(upper(a, b));
  int ans = fenwTree.get(0, tin[b]);
  if (a) {
    ans -= fenwTree.get(0, tin[a] - 1);
  }
  return ans;
}
void dfs0(int v, int p) {
  tin[v] = timer++;
  order.push_back(v);
  par[v][0] = p;
  for (int i = 1; i < LOG; ++i) {
    par[v][i] = par[par[v][i - 1]][i - 1];
  }
  for (int to : g[v]) {
    dfs0(to, v);
  }
  tout[v] = timer++;
  order.push_back(v);
}
void dfs(int v) {
  sum_dp[v] = 0;
  for (int to : g[v]) {
    dfs(to);
    sum_dp[v] += dp[to];
  }
  dp[v] = sum_dp[v];
  auto find_son = [&](int u) {
    int L = 0;
    int R = ((int)(g[v]).size());
    while (L != R - 1) {
      int M = (L + R) / 2;
      if (tin[g[v][M]] <= tin[u]) {
        L = M;
      } else {
        R = M;
      }
    }
    return L;
  };
  for (const auto& e : es_node[v]) {
    int a = e.a;
    int b = e.b;
    assert(a != b);
    if (tin[a] > tin[b]) {
      swap(a, b);
    }
    int cur = e.cost;
    const int b_to = g[v].at(find_son(b));
    if (a == v) {
      cur += sum_dp[b];
      cur += sum_func(b_to, b);
      cur += sum_dp[v] - dp[b_to];
    } else {
      const int a_to = g[v].at(find_son(a));
      cur += sum_dp[a];
      cur += sum_func(a_to, a);
      cur += sum_dp[b];
      cur += sum_func(b_to, b);
      cur += sum_dp[v] - dp[a_to] - dp[b_to];
    }
    dp[v] = max(dp[v], cur);
  }
  for (int to : g[v]) {
    set_func(to, sum_dp[v] - dp[to]);
  }
}
int solve() {
  LOG = 0;
  while ((1 << LOG) < n) {
    ++LOG;
  }
  par.assign(n, vector<int>(LOG));
  timer = 0;
  tin.assign(n, 0);
  tout.assign(n, 0);
  order.clear();
  dfs0(0, 0);
  es_node.clear();
  es_node.resize(n);
  for (const auto& e : es) {
    int lc = lca(e.a, e.b);
    es_node[lc].push_back(e);
  }
  fenwTree = FenwTree(((int)(order).size()));
  dp.assign(n, 0);
  sum_dp.assign(n, 0);
  dfs(0);
  return dp[0];
}
int main() {
  while (read()) {
    printf("%d\n", solve());
  }
  return 0;
}
