#include <bits/stdc++.h>
using namespace std;
using ii = pair<int, int>;
using ll = long long;
const ll INF = 2e15;
const int LOG_K = 17;
const int MAX_ST = 1 << LOG_K;
struct sparse_seg_tree {
  struct node {
    ll mn;
    ll mx;
    ll lazy_add;
    ll lazy_set;
    bool last_add;
    int tl, tr;
    node *left;
    node *right;
    node(int _tl = 0, int _tr = MAX_ST - 1)
        : mn(0LL),
          mx(0LL),
          lazy_add(0LL),
          lazy_set(0LL),
          last_add(false),
          left(nullptr),
          right(nullptr),
          tl(_tl),
          tr(_tr) {}
    void merge() {
      mn = INF;
      mx = 0LL;
      if (left) {
        mn = min(mn, left->mn);
        mx = max(mx, left->mx);
      }
      if (right) {
        mn = min(mn, right->mn);
        mx = max(mx, right->mx);
      }
      if (mn == INF) mn = 0LL;
    }
    void check_left() {
      if (!left) left = new node(tl, (tl + tr - 1) >> 1);
    }
    void check_right() {
      if (!right) right = new node((tl + tr + 1) >> 1, tr);
    }
    void push_lazy_set() {
      mn = mx = lazy_set;
      if (tl < tr) {
        check_left();
        left->lazy_set = lazy_set;
        left->lazy_add = 0LL;
        left->last_add = false;
        check_right();
        right->lazy_set = lazy_set;
        right->lazy_add = 0LL;
        right->last_add = false;
      }
    }
    void push_lazy_add() {
      mn += lazy_add;
      mx += lazy_add;
      if (tl < tr) {
        check_left();
        left->lazy_add += lazy_add;
        left->last_add = true;
        check_right();
        right->lazy_add += lazy_add;
        right->last_add = true;
      }
    }
    void push_lazy() {
      if (lazy_set) push_lazy_set();
      if (last_add && lazy_add) push_lazy_add();
      lazy_add = 0LL;
      lazy_set = 0LL;
    }
    ll _query(node *n, int l, int r) {
      if (n) return n->query(l, r);
      return 0LL;
    }
    ll query(int l, int r) {
      push_lazy();
      if (tl > r || tr < l) return 0LL;
      if (tl >= l && tr <= r) return mx;
      ll res = max(_query(left, l, r), _query(right, l, r));
      merge();
      return res;
    }
    void set(int l, ll new_val) {
      push_lazy();
      if (tr < l || mn >= new_val) return;
      if (tl >= l && mx <= new_val) {
        lazy_set = new_val;
        last_add = false;
        push_lazy();
        return;
      }
      check_left();
      left->set(l, new_val);
      check_right();
      right->set(l, new_val);
      merge();
    }
    void add(int l, ll delta) {
      push_lazy();
      if (tr < l) return;
      if (tl >= l) {
        lazy_add = delta;
        last_add = true;
        push_lazy();
        return;
      }
      check_left();
      left->add(l, delta);
      check_right();
      right->add(l, delta);
      merge();
    }
  };
  node root;
  sparse_seg_tree() : root() {}
  ll get(int val) { return root.query(val, val); }
  void set(int x, ll new_val) { root.set(x, new_val); }
  void add(int x, ll delta) { root.add(x, delta); }
  ll query(int l, int r) { return root.query(l, r); }
};
int n, m, k;
vector<int> parent;
vector<vector<int>> children;
vector<ii> fruit;
vector<vector<int>> active;
vector<ll> last_val;
vector<sparse_seg_tree> seg_tree;
vector<int> self_index;
void solve(int node) {
  self_index[node] = node;
  ii max_child = ii(0, 0);
  for (auto child : children[node]) {
    solve(child);
    max_child = max(max_child, ii(active[self_index[child]].size(), child));
  }
  int big_child = max_child.second;
  struct entry {
    int child_index;
    int day;
    ll val;
    bool operator<(const entry &e) const { return day < e.day; }
  };
  vector<entry> tmp;
  for (auto child : children[node]) {
    if (child == big_child) continue;
    int index = self_index[child];
    last_val[index] = 0LL;
    for (auto it : active[index])
      tmp.push_back({index, it, seg_tree[index].get(it)});
  }
  sort(tmp.begin(), tmp.end());
  int index;
  if (big_child == 0)
    index = self_index[node];
  else
    index = self_index[node] = self_index[big_child];
  for (auto it : tmp) {
    ll delta = it.val - last_val[it.child_index];
    if (delta <= 0) continue;
    last_val[it.child_index] = it.val;
    seg_tree[index].add(it.day, delta);
    active[index].push_back(it.day);
  }
  if (fruit[node].second) {
    int day = fruit[node].first;
    ll val = fruit[node].second;
    seg_tree[index].set(day, val + seg_tree[index].query(0, day));
    active[index].push_back(day);
  }
}
int main() {
  scanf("%d %d %d", &n, &m, &k);
  parent.resize(n + 1, 0);
  fruit.resize(n + 1, ii(0, 0));
  children.resize(n + 1);
  active.resize(n + 1);
  last_val.resize(n + 1);
  seg_tree.resize(n + 1);
  self_index.resize(n + 1);
  for (int i = 2; i <= n; ++i) {
    scanf("%d", &parent[i]);
    children[parent[i]].push_back(i);
  }
  for (int i = 0, v, d, w; i < m; ++i) {
    scanf("%d %d %d", &v, &d, &w);
    fruit[v] = ii(d, w);
  }
  solve(1);
  printf("%lld\n", seg_tree[self_index[1]].query(0, k));
}
