func_code_string: #include <bits/stdc++.h>   using namespace std;   const int MAXN = 100007;   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);         }       }     }     vector<int> 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);       }       vector<int> ret;       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;       }       return ret;     }     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); }     int LCA(int p, int q) {       access(p);       return access(q).back();     }   };   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);     }     map<long long, vector<long long> > mp;     for (int _m = 0; _m < m; _m++) {       int s, t;       cin >> s >> t;       if (s == 1) continue;       vector<int> need = lct.access(s, true);       for (int p : need) {         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;   }   