#include using namespace std; ofstream out("f.out"); const int MOMMAX = 5e5; struct edge { int ti,tf,x,y; }; int n,m,t,q; vectorg[100005]; map,int>color; map,int>beg; vectorv[100005]; vector>qs[100005];///timp,index vector>aint[4 * MOMMAX + 5]; vector>input_edges; vectorinds[4 * MOMMAX + 5]; int ans[100005]; int diammax[4 * MOMMAX + 5]; int tata[100005],sz[100005],diam[100005]; pairbestdiam[100005]; vector rmq[19]; int tin[100005], depth[100005]; void _dfs(int u = 1, int v = 0) { tin[u] = rmq[0].size(); rmq[0].emplace_back(u); for(const auto &it: g[u]) if(it != v) { depth[it] = depth[u] + 1; _dfs(it, u); rmq[0].emplace_back(u); } } int _min(int u, int v) { if(depth[u] < depth[v]) { return u; } return v; } void init() { _dfs(); int n = rmq[0].size(); for(int i = 1; (1 << i) <= n; i++) { for(int j = 0; j + (1 << i) - 1 < n; j++) { rmq[i].emplace_back(_min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))])); } } } int query(int l, int r) { int lg = __lg(r - l + 1); return _min(rmq[lg][l], rmq[lg][r - (1 << lg) + 1]); } int lca(int u, int v) { int l = tin[u], r = tin[v]; if(l > r) { swap(l, r); } return query(l, r); } int dist(int u, int v) { return depth[u] + depth[v] - 2 * depth[lca(u, v)]; } void update(int nod,int l,int r,int st,int dr,pairp) { if (r < st or dr < l) return; if (st <= l and r <= dr) { aint[nod].push_back(p); return; } int mij = (l + r) / 2; update(2 * nod,l,mij,st,dr,p); update(2 * nod + 1,mij + 1,r,st,dr,p); } void setquery(int nod,int l,int r,int pos,int index) { if (l == r) inds[nod].push_back(index); else { int mij = (l + r) / 2; if (pos <= mij) setquery(2 * nod,l,mij,pos,index); else setquery(2 * nod + 1,mij + 1,r,pos,index); } } struct stack_upd { int x,y,antx; pairantbestx; ///x a devenit tatal lui y ///x avea diam antx ///size-ul anterior al lui y o sa ramana in sz[y] ///diametrul anterior al lui y o sa ramane in diam[y] }; stackstk; int reprez(int x) { while (x != tata[x]) x = tata[x]; return x; } void baga(int nod,int x,int y) { //cout << "super" << endl; x = reprez(x); y = reprez(y); if (sz[x] < sz[y]) swap(x,y); stack_upd aux; aux.x = x; aux.y = y; aux.antbestx = bestdiam[x]; aux.antx = diam[x]; stk.push(aux); tata[aux.y] = aux.x; int maxim = max(diam[x],diam[y]); maxim = max(maxim,dist(bestdiam[x].first,bestdiam[y].first)); maxim = max(maxim,dist(bestdiam[x].first,bestdiam[y].second)); maxim = max(maxim,dist(bestdiam[x].second,bestdiam[y].first)); maxim = max(maxim,dist(bestdiam[x].second,bestdiam[y].second)); //cout << x << ' ' << y << ' ' << diam[x] << ' ' << diam[y] << ' ' << dist(bestdiam[x].first,bestdiam[y].first) << ' ' << dist(bestdiam[x].first,bestdiam[y].second) << ' ' << dist(bestdiam[x].second,bestdiam[y].first) << ' ' << dist(bestdiam[x].second,bestdiam[y].second) << endl; diammax[nod] = max(diammax[nod],maxim); if (diam[x] == maxim) { return; } if (diam[y] == maxim) { diam[x] = diam[y]; bestdiam[x] = bestdiam[y]; return; } if (dist(bestdiam[x].first,bestdiam[y].first) == maxim) { diam[x] = dist(bestdiam[x].first,bestdiam[y].first); bestdiam[x] = {bestdiam[x].first,bestdiam[y].first}; return; } if (dist(bestdiam[x].first,bestdiam[y].second) == maxim) { diam[x] = dist(bestdiam[x].first,bestdiam[y].second); bestdiam[x] = {bestdiam[x].first,bestdiam[y].second}; return; } if (dist(bestdiam[x].second,bestdiam[y].first) == maxim) { diam[x] = dist(bestdiam[x].second,bestdiam[y].first); bestdiam[x] = {bestdiam[x].second,bestdiam[y].first}; return; } if (dist(bestdiam[x].second,bestdiam[y].second) == maxim) { diam[x] = dist(bestdiam[x].second,bestdiam[y].second); bestdiam[x] = {bestdiam[x].second,bestdiam[y].second}; return; } } void rollback() { stack_upd aux = stk.top(); stk.pop(); tata[aux.y] = aux.y; sz[aux.x] -= sz[aux.y]; diam[aux.x] = aux.antx; bestdiam[aux.x] = aux.antbestx; } void dfs(int nod,int l,int r) { /*if (!aint[nod].empty()) { cout << nod << ' ' << l << ' ' << r << endl; for (auto it : aint[nod]) cout << it.first << ' ' << it.second << endl; cout << endl; }*/ diammax[nod] = diammax[nod / 2]; for (auto it : aint[nod]) baga(nod,it.first,it.second); //if (!aint[nod].empty() or !inds[nod].empty()) // cout << nod << ' ' << l << ' ' << r << ' ' << diammax[nod] << '\n'; if (l == r) { for (auto it : inds[nod]) ans[it] = diammax[nod]; } else { int mij = (l + r) / 2; dfs(2 * nod,l,mij); dfs(2 * nod + 1,mij + 1,r); } for (int i = 0; i < aint[nod].size(); i++) rollback(); } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> n >> m; for (int i = 1; i < n; i++) { int x,y,cc; cin >> x >> y >> cc; if (x > y) swap(x,y); color[{x,y}] = cc; g[x].push_back(y); g[y].push_back(x); beg[{x,y}] = 1; input_edges.push_back({x,y}); } for (int i = 1; i <= n; i++) tata[i] = i,sz[i] = 1,diam[i] = 0,bestdiam[i] = {i,i}; init(); cin >> t; for (int i = 1; i <= t; i++) { int x,y,cc; cin >> x >> y >> cc; if (x > y) swap(x,y); edge aux; aux.x = x; aux.y = y; aux.ti = beg[{x,y}]; aux.tf = i; v[color[{x,y}]].push_back(aux); color[{x,y}] = cc; beg[{x,y}] = i + 1; } for (int i = 0; i < n - 1; i++) { int x = input_edges[i].first,y = input_edges[i].second; edge aux; aux.x = x; aux.y = y; aux.tf = t + 1; aux.ti = beg[{x,y}]; v[color[{x,y}]].push_back(aux); } cin >> q; for (int i = 1; i <= q; i++) { int cc,tmp; cin >> cc >> tmp; tmp++; qs[cc].push_back({tmp,i}); } int ft = 0; for (int i = 1; i <= m; i++) { //cout << i << endl; vectorvals; for (auto it : v[i]) vals.push_back(it.ti),vals.push_back(it.tf); for (auto it : qs[i]) vals.push_back(it.first); sort(vals.begin(),vals.end()); if (vals.size() == 0) continue; mapmpnorma; int posnorma = 0; for (auto it : vals) if (!mpnorma[it]) mpnorma[it] = ++posnorma; for (int j = 0; j < v[i].size(); j++) v[i][j].ti = mpnorma[v[i][j].ti] + ft,v[i][j].tf = mpnorma[v[i][j].tf] + ft; for (int j = 0; j < qs[i].size(); j++) qs[i][j].first = mpnorma[qs[i][j].first] + ft; //for (auto it : v[i]) // cout << it.ti << ' ' << it.tf << ' ' << it.x << ' ' << it.y << endl; //for (auto it : qs[i]) // cout << it.first << ' ' << it.second << endl; for (int j = 0; j < v[i].size(); j++) update(1,1,MOMMAX,v[i][j].ti,v[i][j].tf,{v[i][j].x,v[i][j].y}); for (int j = 0; j < qs[i].size(); j++) setquery(1,1,MOMMAX,qs[i][j].first,qs[i][j].second); ft += posnorma; } dfs(1,1,MOMMAX); for (int i = 1; i <= q; i++) cout << ans[i] << '\n'; return 0; }