#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define N 150005
#define Q 200005
using namespace std;
typedef long long LL;
int n,q,A,x[N],y[N],head[N],cnt=0;
int father[N],deep[N],pos[N],top[N],siz[N],maxv[N],sz=0;
int rt[N],ls[N*120],rs[N*120],tot=0;
LL sum[N*120],lazy[N*120],dis[N],d[N],w[N],p1[N],p2[N];
LL read()
{
LL x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
struct Node1
{
int next,to,w;
}Edges[N*2];
struct Node2
{
int age,id;
Node2(int age=0,int id=0):age(age),id(id){}
bool operator < (const Node2& t) const
{return age<t.age;}
}data[N];
void addedge(int u,int v,int w)
{
Edges[++cnt].next=head[u];
head[u]=cnt;
Edges[cnt].to=v;
Edges[cnt].w=w;
}
void dfs1(int u)
{
siz[u]=1;
for(int i=head[u];~i;i=Edges[i].next)
{
int v=Edges[i].to;
if(v==father[u])continue;
father[v]=u;
deep[v]=deep[u]+1,d[v]=Edges[i].w,dis[v]=dis[u]+Edges[i].w;
dfs1(v);siz[u]+=siz[v];
if(!maxv[u]||siz[v]>siz[maxv[u]])maxv[u]=v;
}
}
void dfs2(int u,int t)
{
top[u]=t;
++sz,pos[u]=sz;
w[sz]=w[sz-1]+d[u],p1[x[u]]++,p2[x[u]]+=dis[u];
if(maxv[u])dfs2(maxv[u],t);
for(int i=head[u];~i;i=Edges[i].next)
{
int v=Edges[i].to;
if(v==maxv[u]||v==father[u])continue;
dfs2(v,v);
}
}
void insert(int &idx,int last,int l,int r,int L,int R)
{
++tot,idx=tot;
sum[idx]=sum[last],lazy[idx]=lazy[last],ls[idx]=ls[last],rs[idx]=rs[last];
if(L==l&&R==r){lazy[idx]++;sum[idx]+=w[r]-w[l-1];return;}
int mid=(l+r)>>1;
if(R<=mid)insert(ls[idx],ls[last],l,mid,L,R);
else if(L>mid)insert(rs[idx],rs[last],mid+1,r,L,R);
else insert(ls[idx],ls[last],l,mid,L,mid),insert(rs[idx],rs[last],mid+1,r,mid+1,R);
sum[idx]=sum[ls[idx]]+sum[rs[idx]]+lazy[idx]*(w[r]-w[l-1]);
}
LL query(int s,int t,int l,int r,int L,int R,int tag)
{
if(L==l&&R==r)return sum[s]-sum[t]+1LL*tag*(w[r]-w[l-1]);
int mid=(l+r)>>1;tag+=lazy[s]-lazy[t];
if(R<=mid)return query(ls[s],ls[t],l,mid,L,R,tag);
else if(L>mid)return query(rs[s],rs[t],mid+1,r,L,R,tag);
else return query(ls[s],ls[t],l,mid,L,mid,tag)+query(rs[s],rs[t],mid+1,r,mid+1,R,tag);
}
void add(int i,int x)
{
while(x)
{
insert(rt[data[i].age],rt[data[i].age],1,sz,pos[top[x]],pos[x]);
x=father[top[x]];
}
}
LL ask(int l,int r,int u)
{
LL res=0;
while(u)
{
res+=query(rt[r],rt[l-1],1,sz,pos[top[u]],pos[u],0);
u=father[top[u]];
}
return res;
}
int main()
{
memset(head,-1,sizeof(head));
n=read(),q=read(),A=read();
for(int i=1;i<=n;i++)y[i]=x[i]=read();
sort(y+1,y+1+n);
int t=unique(y+1,y+1+n)-y-1;
for(int i=1;i<=n;i++)x[i]=lower_bound(y+1,y+1+t,x[i])-y;
for(int i=1;i<n;i++)
{
int a=read(),b=read(),c=read();
addedge(a,b,c),addedge(b,a,c);
}
dfs1(1);dfs2(1,1);
for(int i=1;i<=n;i++)data[i]=Node2(x[i],i);
sort(data+1,data+1+n);
for(int i=1;i<=n;i++)
{
if(!rt[data[i].age])
rt[data[i].age]=rt[data[i].age-1];
add(i,data[i].id);
}
for(int i=1;i<=t;i++)p1[i]+=p1[i-1],p2[i]+=p2[i-1];
LL last=0;
for(int i=1;i<=q;i++)
{
LL u=read(),a=read(),b=read();
int l=min((a+last)%A,(b+last)%A),r=max((a+last)%A,(b+last)%A);
l=lower_bound(y+1,y+1+t,l)-y,r=upper_bound(y+1,y+1+t,r)-y-1;
if(l>r||l>t||r<1){last=0;printf("0\n");continue;}
last=dis[u]*(p1[r]-p1[l-1])+p2[r]-p2[l-1]-2*ask(l,r,u);
printf("%lld\n",last);
}
return 0;
}