#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+5;
struct segmenttree
{
vector< pair<long long,long long> > seg;
int N;
void build(int n)
{
N=n;
seg.resize(n*4);
}
void update(int l,int r,int i,long long val,int pos)
{
if(i<l||r<i) return ;
if(l==r)
{
seg[pos].first+=val,seg[pos].second+=val;
return ;
}
int mid=(l+r)/2;
update(l,mid,i,val,pos*2);
update(mid+1,r,i,val,pos*2+1);
seg[pos].first=seg[pos*2].first+seg[pos*2+1].first;
seg[pos].second=max(seg[pos*2].second,seg[pos*2].first+seg[pos*2+1].second);
}
void update(int l,int r,long long val)
{
update(1,N,l,val,1);
update(1,N,r+1,-val,1);
}
};
struct edge
{
long long nex,pos,val;
};
struct query
{
int p,l,r;
};
vector<edge> ds[MAXN];
vector<query> vq[MAXN];
long long len[MAXN],edge[MAXN],F[MAXN],seg[MAXN*4];
int sub[MAXN],L[MAXN],R[MAXN],rt[MAXN],tdfs=0,cnt=0;
bool ck[MAXN];
segmenttree st[MAXN];
set< pair<long long,int> > val[MAXN];
void update(int l,int r,int i,long long val,int pos)
{
if(i<l||r<i) return ;
if(l==r)
{
seg[pos]=val;
return ;
}
int mid=(l+r)/2;
update(l,mid,i,val,pos*2);
update(mid+1,r,i,val,pos*2+1);
seg[pos]=max(seg[pos*2],seg[pos*2+1]);
}
void dfs(int i,int pre)
{
sub[i]=1;
for(auto v:ds[i]) if(v.nex!=pre&&!ck[v.nex])
{
dfs(v.nex,i);
sub[i]+=sub[v.nex];
}
}
void dfs2(int i,int pre,int root)
{
L[i]=++tdfs;
for(auto v:ds[i]) if(v.nex!=pre&&!ck[v.nex])
{
dfs2(v.nex,i,root);
vq[v.pos].push_back({root,L[v.nex],R[v.nex]});
}
R[i]=tdfs;
}
int centroid(int i,int pre,int cnt)
{
for(auto v:ds[i]) if(v.nex!=pre&&!ck[v.nex]&&sub[v.nex]*2>cnt) return centroid(v.nex,i,cnt);
return i;
}
void decomp(int i)
{
dfs(i,i);
int pos=centroid(i,i,sub[i]);
ck[pos]=true;
for(auto v:ds[pos]) if(!ck[v.nex])
{
tdfs=0,cnt++;
dfs2(v.nex,v.nex,cnt);
st[cnt].build(tdfs),vq[v.pos].push_back({cnt,1,tdfs}),rt[cnt]=pos,val[pos].insert({0,cnt});
decomp(v.nex);
}
}
void update(int i,int n,long long w)
{
w-=edge[i];
for(auto v:vq[i])
{
val[rt[v.p]].erase({F[v.p],v.p});
st[v.p].update(v.l,v.r,w);
val[rt[v.p]].insert({F[v.p]=st[v.p].seg[1].second,v.p});
auto res=prev(val[rt[v.p]].end());
if(res==val[rt[v.p]].begin()) update(1,n,rt[v.p],(*res).first,1);
else update(1,n,rt[v.p],(*res).first+(*prev(res)).first,1);
}
edge[i]+=w;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,q;
long long w;
cin>>n>>q>>w;
for(int i=1;i<n;i++)
{
long long l,r,v;
cin>>l>>r>>v;
len[i]=v;
ds[l].push_back({r,i,v}),ds[r].push_back({l,i,v});
}
decomp(1);
for(int i=1;i<n;i++) update(i,n,len[i]);
long long last=0;
for(int i=1;i<=q;i++)
{
long long d,e;
cin>>d>>e;
d=(d+last)%(n-1),e=(e+last)%w;
update(d+1,n,e);
cout<<(last=seg[1])<<"\n";
}
}