#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define f first
#define all(x) x.begin(),x.end()
#define s second
#define pll pair<long long, long long>
#define sz(x) (int)x.size()
const int maxn=100005, maxq=100005, inf=2e18+5;
struct node{
int s, e, m, v, lz;
node *l, *r;
node(int S, int E){
s=S, e=E, m=(s+e)/2, v=0, lz=0;
if(s!=e){
l=new node(s, m);
r=new node(m+1, e);
}
}
void prop(){
if(lz==0 or s==e) return;
l->v += lz, r->v += lz, l->lz += lz, r->lz += lz;
lz=0;
}
int combine(int a, int b){
return max(a, b);
}
void upd(int S, int E, int DV){
if(S<=s and e<=E){
v += DV;
lz += DV;
return;
}
prop();
if(E <= m) l->upd(S, E, DV);
else if(S > m)r->upd(S, E, DV);
else l->upd(S, m, DV), r->upd(m+1, E, DV);
v=combine(l->v, r->v);
}
int qry(int S, int E){
if(S<=s and e<=E){
return v;
}
prop();
if(E <= m) return l->qry(S,E);
else if(S > m) return r->qry(S,E);
return combine(l->qry(S, m), r->qry(m+1, E));
}
} *root[maxn];
int n, q, w;
vector<vector<pair<int,int>>> al(maxn);
vector<int> lay(maxn, inf), ss(maxn), st(maxn, 0), oridep(maxn, 0), len(maxn, 0), cpar(maxn);
vector<vector<int>> in(maxn), out(maxn);
multiset<pll> cands;
vector<int> centans(maxn);
vector<multiset<pll>> path(maxn), childinpathvalue(maxn);
int t=0;
void subtree_size(int x, int p, int layer){
ss[x]=1;
for(auto [it, w] : al[x]){
if(it==p or lay[it] <= layer)continue;
subtree_size(it, x, layer);
ss[x] += ss[it];
}
}
int find_centroid(int x, int p, int layer, int full){
for(auto [it, w] : al[x]){
if(it==p or lay[it] <= layer)continue;
if(ss[it] > full/2) return find_centroid(it, x, layer, full);
}
return x;
}
void dfs(int x, int p, int head, int cd){
root[head]->upd(t, t, cd);
in[x].push_back(t++);
for(auto [it, w] : al[x]){
if(it == p or lay[it] <= lay[head])continue;
if(lay[head] == 0){
len[it]=w;
oridep[it]=oridep[x]+1;
}
int beft=t;
dfs(it, x, head, cd + w);
if(p == -1){
int childdep=root[head]->qry(beft, t-1);
path[head].insert({childdep, beft});
childinpathvalue[head].insert({beft, childdep});
}
}
out[x].push_back(t-1);
}
int calcdia(int cent){
int top1=(sz(path[cent]) >= 1 ? prev(path[cent].end())->f : 0);
int top2=(sz(path[cent]) >= 2 ? prev(prev(path[cent].end()))->f : 0);
return top1+top2;
}
int build(int x, int par, int layer){
subtree_size(x, -1, layer);
int cent=find_centroid(x, -1, layer, ss[x]);
lay[cent]=layer;
t=0;
root[cent]=new node(0, ss[x]-1);
dfs(cent, -1, cent, 0);
centans[cent] = calcdia(cent);
cands.insert({centans[cent], cent});
childinpathvalue[cent].insert({ss[x], 0});
/*printf("centroid %lld subtree size %lld", cent, ss[x]);
cout<<endl;
printf("centroid %lld, paths : ", cent);
for(auto [tin, leng] : childinpathvalue[cent]) printf(" (%lld, %lld) ", tin, leng);
cout<<endl;
printf("centroid %lld, dia here is %lld\n\n", cent, centans[cent]);*/
cpar[cent]=par;
//printf("centroid %lld layer %lld, parent %lld\n", cent, layer, par);
for(auto [it, w] : al[cent]){
if(lay[it] == inf) build(it, cent, layer+1);
}
return cent;
}
signed main(){
//ios_base::sync_with_stdio(false);
//cin.tie(0);
cin>>n>>q>>w;
vector<pll> ed(n-1);
for (int i=1;i<=n-1;i++){
int a,b,c;cin>>a>>b>>c;
ed[i-1] = {a, b};
al[a].push_back({b,c});
al[b].push_back({a,c});
}
build(1, -1, 0);
/*for(int i=1;i<=n;i++){
cout<<len[i]<<" "<<oridep[i]<<"\n";
}
cout<<endl;*/
/*for(int i=1;i<=n;i++){
printf("node i %lld : \n", i);
for(auto j : in[i]){
cout<<j <<" ";
}
cout<<endl;
for(auto j : out[i]){
cout<<j <<" ";
}
for(int j=0;j<(int)in[i].size();j++){
printf(" (%lld, %lld) ", in[i][j], out[i][j]);
}
cout<<endl;
}*/
int last=0;
for(int qind=0;qind<q;qind++){
int eind, nww;cin>>eind>>nww;
eind = (eind + last) % (n-1);
nww = (nww + last) % w;
auto [x, y] = ed[eind];
assert(lay[x] != lay[y]);
assert(oridep[x] != oridep[y]);
int cn=(lay[x] < lay[y] ? x : y);
int lower=(oridep[x] < oridep[y] ? y : x);
int dv=nww-len[lower];
//printf("x %lld y %lld, %lld nww %lld\n", x, y, lower, nww);
//printf("dv is %lld\n", dv);
len[lower]=nww;
while(cn != -1){
int tofind=(in[x][lay[cn]] < in[y][lay[cn]] ? y : x);
auto it = upper_bound(all(childinpathvalue[cn]), make_pair(in[tofind][lay[cn]], (int)1e15));
assert(it != childinpathvalue[cn].end() and it != childinpathvalue[cn].begin());
auto [intime, bestpath] = *prev(it);
auto [nextintime, _b] = *it;
childinpathvalue[cn].erase(prev(it));
auto pathentry = path[cn].find({bestpath, intime});
assert(pathentry != path[cn].end());
path[cn].erase(pathentry);
auto candsentry = cands.find({centans[cn], cn});
assert(candsentry != cands.end());
cands.erase(candsentry);
if(in[x][lay[cn]] < in[y][lay[cn]]){ // x is higher than y, upd y subtree
root[cn]->upd(in[y][lay[cn]], out[y][lay[cn]], dv);
}
else {//update x subtree;
root[cn]->upd(in[x][lay[cn]], out[x][lay[cn]], dv);
}
int nwpath=root[cn]->qry(intime, nextintime-1);
childinpathvalue[cn].insert({intime, nwpath});
path[cn].insert({nwpath, intime});
centans[cn] = calcdia(cn);
cands.insert({centans[cn], cn});
cn = cpar[cn];
}
last = prev(cands.end())->f;
cout<<last<<'\n';
}
}