#include <bits/stdc++.h>
using namespace std;
template <class node>
struct link_cut_tree {
  bool connected(node* u, node* v) { return lca(u, v) != NULL; }
  int depth(node* u) {
    access(u);
    return get_sz(u->ch[0]);
  }
  node* get_root(node* u) {
    access(u);
    while (u->ch[0]) u = u->ch[0], u->push();
    return access(u), u;
  }
  node* ancestor(node* u, int k) {
    k = depth(u) - k;
    for (;; u->push()) {
      int sz = get_sz(u->ch[0]);
      if (sz == k) return access(u), u;
      if (sz < k)
        k -= sz + 1, u = u->ch[1];
      else
        u = u->ch[0];
    }
  }
  node* lca(node* u, node* v) {
    if (u == v) return u;
    access(u);
    access(v);
    if (!u->p) return NULL;
    u->splay();
    return u->p ?: u;
  }
  void link(node* u, node* v) {
    make_root(v);
    access(u);
    set_link(v, u, 0);
    v->update();
  }
  void cut(node* u) {
    access(u);
    u->ch[0]->p = NULL;
    u->ch[0] = NULL;
    u->update();
  }
  void cut(node* u, node* v) { cut(depth(u) > depth(v) ? u : v); }
  void make_root(node* u) {
    access(u);
    u->rev ^= 1;
    access(u);
  }
  void access(node* u) {
    for (node *v = u, *pre = NULL; v; v = v->p) {
      v->splay();
      if (pre) v->update_vsub(pre, false);
      if (v->ch[1]) v->update_vsub(v->ch[1], true);
      v->ch[1] = pre;
      v->update();
      pre = v;
    }
    u->splay();
  }
  node* operator[](int i) { return &data[i]; }
  int operator[](node* i) { return i - &data[0]; }
  vector<node> data;
  link_cut_tree(int n) : data(n) {}
};
template <typename pnode>
struct splay_tree {
  pnode ch[2], p;
  bool rev;
  int sz;
  splay_tree() {
    ch[0] = ch[1] = p = NULL;
    rev = 0;
    sz = 1;
  }
  friend int get_sz(pnode u) { return u ? u->sz : 0; }
  virtual void update() {
    if (ch[0]) ch[0]->push();
    if (ch[1]) ch[1]->push();
    sz = 1 + get_sz(ch[0]) + get_sz(ch[1]);
  }
  virtual void push() {
    if (rev) {
      if (ch[0]) ch[0]->rev ^= 1;
      if (ch[1]) ch[1]->rev ^= 1;
      swap(ch[0], ch[1]);
      rev = 0;
    }
  }
  int dir() {
    if (!p) return -2;
    if (p->ch[0] == this) return 0;
    if (p->ch[1] == this) return 1;
    return -1;
  }
  bool is_root() { return dir() < 0; }
  friend void set_link(pnode u, pnode v, int d) {
    if (v) v->p = u;
    if (d >= 0) u->ch[d] = v;
  }
  void rotate() {
    int x = dir();
    pnode g = p;
    set_link(g->p, static_cast<pnode>(this), g->dir());
    set_link(g, ch[x ^ 1], x);
    set_link(static_cast<pnode>(this), g, x ^ 1);
    g->update();
    update();
  }
  void splay() {
    while (!is_root() && !p->is_root()) {
      p->p->push(), p->push(), push();
      dir() == p->dir() ? p->rotate() : rotate();
      rotate();
    }
    if (!is_root()) p->push(), push(), rotate();
    push();
  }
};
struct node;
node* root;
bool capture;
vector<pair<int, int>> vec;
struct node : splay_tree<node*> {
  using splay_tree::ch;
  int val, lazy;
  node() : splay_tree() {
    val = -1e9;
    lazy = -1;
  }
  void update() override { splay_tree::update(); }
  void update_vsub(node* v, bool add) {
    if (!add && capture) vec.push_back({this - root, val});
  }
  void push() override {
    splay_tree::push();
    if (lazy != -1) {
      val = lazy;
      if (ch[0]) ch[0]->lazy = lazy;
      if (ch[1]) ch[1]->lazy = lazy;
      lazy = -1;
    }
  }
};
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0);
  int n, m;
  cin >> n >> m;
  vector<vector<pair<int, int>>> adj(n);
  for (int i = 1, u, v, w; i < n; ++i) {
    cin >> u >> v >> w;
    --u, --v;
    adj[u].push_back({v, w});
  }
  vector<long long> dist(n);
  vec.reserve(n);
  link_cut_tree<node> lct(n);
  function<void(int)> dfs_access = [&](int u) {
    for (auto v : adj[u]) {
      dist[v.first] = dist[u] + v.second;
      lct.link(lct[u], lct[v.first]);
      dfs_access(v.first);
    }
  };
  dfs_access(0);
  root = lct[0];
  vector<pair<long long, long long>> s;
  for (int i = 0, d, t; i < m; ++i) {
    cin >> d >> t;
    --d;
    auto u = lct[d], v = u;
    while (!v->is_root()) v = v->p, v->push();
    while (v->ch[1]) v = v->ch[1], v->push();
    vec.clear();
    capture = true;
    lct.access(u);
    capture = false;
    for (auto x : vec)
      s.push_back({dist[x.first] + x.second, dist[x.first] + t});
    int val = u->val;
    u->lazy = t;
    u->push();
    u->val = val;
    lct.access(v);
  }
  long long explosion = -1, changes = s.size();
  sort(s.begin(), s.end());
  priority_queue<long long, vector<long long>, greater<long long>> pq;
  for (long long t = 1, i = 0; i < s.size() || !pq.empty();) {
    if (pq.empty() && t <= s[i].first) t = s[i].first + 1;
    while (i < s.size() && s[i].first < t) pq.push(s[i].second), ++i;
    if (t > pq.top()) {
      explosion = t - 1;
      break;
    }
    pq.pop();
    ++t;
  }
  if (explosion != -1)
    changes -= count_if(s.begin(), s.end(), [&](pair<long long, long long> x) {
      return x.second >= explosion;
    });
  cout << explosion << " " << changes << "\n";
  return 0;
}
