#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100007;
vector<int> ret;
struct LinkCutTree {
  struct Node {
    int L, R, P, lazyFlip;
    int PP;
  };
  Node LCT[MAXN];
  void normalize(int u) {
    assert(u != -1);
    if (LCT[u].L != -1) LCT[LCT[u].L].P = u;
    if (LCT[u].R != -1) LCT[LCT[u].R].P = u;
  }
  void setLeftChild(int p, int v) {
    LCT[p].L = v;
    normalize(p);
  }
  void setRightChild(int p, int v) {
    LCT[p].R = v;
    normalize(p);
  }
  void pushLazy(int u) {
    if (!LCT[u].lazyFlip) return;
    swap(LCT[u].L, LCT[u].R);
    LCT[u].lazyFlip = 0;
    if (LCT[u].L != -1) LCT[LCT[u].L].lazyFlip ^= 1;
    if (LCT[u].R != -1) LCT[LCT[u].R].lazyFlip ^= 1;
  }
  void make_tree(int v) {
    LCT[v].L = LCT[v].R = LCT[v].P = LCT[v].PP = -1;
    LCT[v].lazyFlip = 0;
  }
  void rotate(int v) {
    if (LCT[v].P == -1) return;
    int p = LCT[v].P;
    int g = LCT[p].P;
    if (LCT[p].L == v) {
      setLeftChild(p, LCT[v].R);
      setRightChild(v, p);
    } else {
      setRightChild(p, LCT[v].L);
      setLeftChild(v, p);
    }
    LCT[v].P = g;
    if (g != -1) {
      if (LCT[g].L == p) {
        setLeftChild(g, v);
      } else {
        setRightChild(g, v);
      }
    }
    LCT[v].PP = LCT[p].PP;
    LCT[p].PP = -1;
  }
  void pushEmAll(int v) {
    if (LCT[v].P != -1) pushEmAll(LCT[v].P);
    pushLazy(v);
  }
  void splay(int v) {
    pushLazy(v);
    while (LCT[v].P != -1) {
      int p = LCT[v].P;
      int g = LCT[p].P;
      if (g != -1) pushLazy(g);
      pushLazy(p);
      pushLazy(v);
      if (g == -1) {
        rotate(v);
      } else if ((LCT[p].L == v) == (LCT[g].L == p)) {
        rotate(p);
        rotate(v);
      } else {
        rotate(v);
        rotate(v);
      }
    }
  }
  void access(int v, bool doIt = false) {
    splay(v);
    int _v = v, _r = -1;
    if (LCT[v].R != -1) {
      if (doIt) {
        _r = LCT[v].R;
      }
      LCT[LCT[v].R].PP = v;
      LCT[LCT[v].R].P = -1;
      setRightChild(v, -1);
    }
    while (LCT[v].PP != -1) {
      int w = LCT[v].PP;
      splay(w);
      ret.push_back(w);
      if (LCT[w].R != -1) {
        LCT[LCT[w].R].PP = w;
        LCT[LCT[w].R].P = -1;
      }
      LCT[v].PP = -1;
      setRightChild(w, v);
      splay(v);
    }
    if (_r != -1) {
      splay(_v);
      assert(LCT[_v].R == -1);
      setRightChild(_v, _r);
      LCT[_r].PP = -1;
    }
  }
  int find_root(int v) {
    access(v);
    int ret = v;
    while (LCT[ret].L != -1) {
      ret = LCT[ret].L;
      pushLazy(ret);
    }
    access(ret);
    return ret;
  }
  void link(int v, int w) {
    access(w);
    setLeftChild(v, w);
    LCT[w].PP = -1;
  }
  void cut(int v) {
    access(v);
    if (LCT[v].L != -1) {
      LCT[LCT[v].L].P = -1;
      LCT[LCT[v].L].PP = -1;
      setLeftChild(v, -1);
    }
  }
  void make_root(int v) {
    access(v);
    int l = LCT[v].L;
    if (l != -1) {
      setLeftChild(v, -1);
      LCT[l].P = -1;
      LCT[l].PP = v;
      LCT[l].lazyFlip ^= 1;
    }
  }
  bool isConnected(int p, int q) { return find_root(p) == find_root(q); }
};
vector<pair<int, int> > edg[MAXN];
long long depth[MAXN];
LinkCutTree lct;
int bap[MAXN];
vector<int> accessOrder;
int st[MAXN], ed[MAXN];
int tym;
void dfs(int u, int p) {
  st[u] = ++tym;
  bap[u] = p;
  bool called = false;
  for (pair<int, int> pr : edg[u]) {
    if (p == pr.first) continue;
    called = true;
    depth[pr.first] = depth[u] + pr.second;
    lct.link(pr.first, u);
    dfs(pr.first, u);
  }
  if (!called) accessOrder.push_back(u);
  ed[u] = tym;
}
map<long long, long long> vacancy;
bool makePlace(long long l, long long r) {
  auto it = vacancy.lower_bound(l);
  if (l <= prev(it)->second) {
    it = prev(it);
    long long _l = it->first;
    long long _r = it->second;
    vacancy.erase(it);
    if (_l < l) vacancy[_l] = l - 1;
    if (l < _r) vacancy[l + 1] = _r;
    return true;
  } else {
    assert(it != vacancy.end());
    long long _l = it->first;
    long long _r = it->second;
    if (r < _l) return false;
    vacancy.erase(it);
    if (_l < _r) vacancy[_l + 1] = _r;
    return true;
  }
  assert(false);
}
set<int> tr[4 * MAXN];
void update(int u, int l, int r, int i, int t) {
  tr[u].insert(t);
  if (l == r) return;
  int mid = (l + r) / 2;
  if (i <= mid)
    update(u * 2, l, mid, i, t);
  else
    update(u * 2 + 1, mid + 1, r, i, t);
}
int ask(int u, int l, int r, int x, int y, int t) {
  if (y < l || r < x) return 0;
  if (x <= l && r <= y) {
    auto it = tr[u].lower_bound(t);
    if (it == tr[u].begin()) return 0;
    return *prev(it);
  }
  int mid = (l + r) / 2;
  return max(ask(u * 2, l, mid, x, y, t), ask(u * 2 + 1, mid + 1, r, x, y, t));
}
void printEdges(int s) {
  while (s != 1) {
    cout << s << "@" << depth[s] << " <- ";
    s = bap[s];
  }
  cout << 1;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i < n; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    edg[u].emplace_back(v, w);
    edg[v].emplace_back(u, w);
  }
  for (int i = 1; i <= n; i++) lct.make_tree(i);
  dfs(1, 0);
  for (int leaf : accessOrder) {
    lct.access(leaf);
  }
  ret.reserve(MAXN * 18);
  map<long long, vector<long long> > mp;
  for (int _m = 0; _m < m; _m++) {
    int s, t;
    cin >> s >> t;
    if (s == 1) continue;
    int sz = ret.size();
    lct.access(s, true);
    for (int _ = sz; _ < ret.size(); _++) {
      int p = ret[_];
      int l = ask(1, 1, n, st[p], ed[p], t);
      if (l > 0)
        mp[t + depth[p]].push_back(l + 1 + depth[p]);
      else
        mp[t + depth[p]].push_back(1);
    }
    update(1, 1, n, st[bap[s]], t);
  }
  vacancy[0] = 1e15;
  int ans = 0;
  for (pair<const long long, vector<long long> >& pr : mp) {
    sort(pr.second.begin(), pr.second.end());
    bool okay = true;
    for (long long x : pr.second) {
      if (!makePlace(x, pr.first)) {
        okay = false;
        break;
      }
    }
    if (!okay) {
      cout << pr.first << " " << ans << endl;
      return 0;
    }
    ans += pr.second.size();
  }
  cout << -1 << " " << ans << endl;
  return 0;
}
