#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+5;
struct segmenttree
{
vector<long long> seg,lazy;
int N;
void build(int n)
{
N=n;
seg.resize(n*4),lazy.resize(n*4);
}
void down(int pos)
{
long long val=lazy[pos];
seg[pos*2]+=val,seg[pos*2+1]+=val;
lazy[pos*2]+=val,lazy[pos*2+1]+=val;
lazy[pos]=0;
}
void update(int l,int r,int u,int v,long long val,int pos)
{
if(v<l||r<u) return ;
if(u<=l&&r<=v)
{
seg[pos]+=val,lazy[pos]+=val;
return ;
}
int mid=(l+r)/2;
down(pos);
update(l,mid,u,v,val,pos*2);
update(mid+1,r,u,v,val,pos*2+1);
seg[pos]=max(seg[pos*2],seg[pos*2+1]);
}
void update(int l,int r,long long val)
{
update(1,N,l,r,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],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";
}
}