#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define rep(s,t) for(int i=s;i<=t;i++)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
inline int read() {
char ch=getchar();int x=0,f=1;
for(;!isdigit(ch);ch=getchar()) if(ch==‘-‘) f=-1;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-‘0‘;
return x*f;
}
const int maxn=300010;
typedef long long LL;
int n,q,first[maxn],next[maxn],to[maxn],dis[maxn],e;
void AddEdge(int w,int v,int u) {
to[++e]=v;dis[e]=w;next[e]=first[u];first[u]=e;
to[++e]=u;dis[e]=w;next[e]=first[v];first[v]=e;
}
int mn[maxn][20],dep[maxn],pos[maxn],cnt;
void dfs(int x,int fa) {
mn[++cnt][0]=dep[x];pos[x]=cnt;
ren if(to[i]!=fa) {
dep[to[i]]=dep[x]+dis[i];
dfs(to[i],x);
mn[++cnt][0]=dep[x];
}
}
int Log[maxn];
void init() {
Log[0]=-1;rep(1,cnt) Log[i]=Log[i>>1]+1;
for(int j=1;(1<<j)<=cnt;j++)
for(int i=1;i+(1<<j)-1<=cnt;i++)
mn[i][j]=min(mn[i][j-1],mn[i+(1<<j-1)][j-1]);
}
LL dist(int x,int y) {
LL ans=dep[x]+dep[y];x=pos[x];y=pos[y];if(x>y) swap(x,y);
int k=Log[y-x+1];
return ans-2LL*min(mn[x][k],mn[y-(1<<k)+1][k]);
}
int age[maxn],vis[maxn],f[maxn],s[maxn],size,root;
void getroot(int x,int fa) {
s[x]=1;int maxs=0;
ren if(!vis[to[i]]&&to[i]!=fa) getroot(to[i],x),s[x]+=s[to[i]],maxs=max(maxs,s[to[i]]);
f[x]=max(maxs,size-s[x]);
if(f[root]>f[x]) root=x;
}
struct Arr {
int c;LL val;
bool operator < (const Arr& ths) const {return c<ths.c;}
Arr operator - (const Arr& ths) const {Arr t;t.val=val-ths.val;t.c=c-ths.c;return t;}
}A[maxn*30];
int cur,L1[maxn],R1[maxn],L2[maxn],R2[maxn];
void dfs(int x,int fa,int dep) {
A[++cur]=(Arr){age[x],dep};s[x]=1;
ren if(to[i]!=fa&&!vis[to[i]]) dfs(to[i],x,dep+dis[i]),s[x]+=s[to[i]];
}
int fa[maxn];
void solve(int x,int F) {
vis[x]=1;fa[x]=F;
A[++cur]=(Arr){-1,0};L1[x]=cur;dfs(x,0,0);R1[x]=cur;
sort(A+L1[x],A+R1[x]+1);
rep(L1[x]+1,R1[x]) A[i].val+=A[i-1].val;
ren if(!vis[to[i]]) {
size=f[0]=s[to[i]];getroot(to[i],root=0);
A[++cur]=(Arr){-1,0};L2[root]=cur;dfs(to[i],0,dis[i]);R2[root]=cur;
sort(A+L2[root],A+R2[root]+1);
rep(L2[root]+1,R2[root]) A[i].val+=A[i-1].val;
solve(root,x);
}
}
LL lastans,T;
Arr get(int x,int ql,int qr,int L,int R) {
Arr t;
t.c=qr;
int pos1=upper_bound(A+L,A+R+1,t)-A-1;
t.c=ql-1;
int pos2=upper_bound(A+L,A+R+1,t)-A-1;
t.c=pos1-pos2;t.val=A[pos1].val-A[pos2].val;
return t;
}
LL query(int x,int l,int r) {
LL ret=get(x,l,r,L1[x],R1[x]).val;
for(int i=x;fa[i];i=fa[i]) {
Arr t=get(fa[i],l,r,L1[fa[i]],R1[fa[i]])-get(i,l,r,L2[i],R2[i]);
ret+=t.val+t.c*dist(fa[i],x);
}
return ret;
}
int main() {
n=read();q=read();T=read();
rep(1,n) age[i]=read();
rep(2,n) AddEdge(read(),read(),read());
dfs(1,0);init();
size=f[0]=n;getroot(1,root=0);
int t=root;solve(root,0);root=t;
while(q--) {
int u=read(),a=(read()+lastans)%T,b=(read()+lastans)%T;
if(a>b) swap(a,b);
printf("%lld\n",lastans=query(u,a,b));
}
return 0;
}