#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;   }