#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll ans;
int n,m;
int tot;
int cnt;
int num;
int A,k;
int l,r;
int x,y,z;
int p[150010];
int h[150010];
int f[150010];
int g[150010];
int q[150010];
int v[150010];
int to[300010];
ll s[20000010];
ll sum[150010];
int dep[150010];
int t[20000010];
int son[150010];
int top[150010];
int val[300010];
int head[150010];
int size[150010];
int next[300010];
int root[150010];
int ls[20000010];
int rs[20000010];
ll total[150010];
struct node
{
    int x;
    int id;
}a[150010];
bool cmp(node a,node b)
{
    return a.x<b.x;
}
void add(int x,int y,int z)
{
    tot++;
    next[tot]=head[x];
    head[x]=tot;
    to[tot]=y;
    val[tot]=z;
}
void dfs(int x)
{
    size[x]=1;
    for(int i=head[x];i;i=next[i])
    {
        if(to[i]!=f[x])
        {
            dep[to[i]]=dep[x]+val[i];
            f[to[i]]=x;
            v[to[i]]=val[i];
            dfs(to[i]);
            size[x]+=size[to[i]];
            if(size[to[i]]>size[son[x]])
            {
                son[x]=to[i];
            }
        }
    }
}
void dfs2(int x,int tp)
{
    top[x]=tp;
    p[x]=++num;
    q[num]=x;
    if(son[x])
    {
        dfs2(son[x],tp);
    }
    for(int i=head[x];i;i=next[i])
    {
        if(to[i]!=f[x]&&to[i]!=son[x])
        {
            dfs2(to[i],to[i]);
        }
    }
}
void pushup(int rt,int l,int r)
{
    s[rt]=s[ls[rt]]+s[rs[rt]]+t[rt]*(sum[r]-sum[l-1]);
}
void change(int &rt,int pre,int l,int r,int L,int R)
{
    rt=++cnt;
    ls[rt]=ls[pre];
    rs[rt]=rs[pre];
    s[rt]=s[pre];
    t[rt]=t[pre];
    if(L<=l&&r<=R)
    {
        t[rt]++;
        s[rt]+=sum[r]-sum[l-1];
        return ;
    }
    int mid=(l+r)>>1;
    if(L<=mid)
    {
        change(ls[rt],ls[pre],l,mid,L,R);
    }
    if(R>mid)
    {
        change(rs[rt],rs[pre],mid+1,r,L,R);
    }
    pushup(rt,l,r);
}
ll query(int rt,int l,int r,int L,int R)
{
    if(L<=l&&r<=R)
    {
        return s[rt];
    }
    ll res=1ll*t[rt]*(sum[min(r,R)]-sum[max(l,L)-1]);
    int mid=(l+r)>>1;
    if(L<=mid)
    {
        res+=query(ls[rt],l,mid,L,R);
    }
    if(R>mid)
    {
        res+=query(rs[rt],mid+1,r,L,R);
    }
    return res;
}
void updata(int x,int rt)
{
    while(top[x]!=1)
    {
        change(root[rt],root[rt],1,n,p[top[x]],p[x]);
        x=f[top[x]];
    }
    change(root[rt],root[rt],1,n,1,p[x]);
}
ll find(int x,int l,int r)
{
    ll res=0;
    while(top[x]!=1)
    {
        res+=query(root[r],1,n,p[top[x]],p[x])-query(root[l],1,n,p[top[x]],p[x]);
        x=f[top[x]];
    }
    res+=query(root[r],1,n,1,p[x])-query(root[l],1,n,1,p[x]);
    return res;
}
int main()
{
    scanf("%d%d%d",&n,&m,&A);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i].x);
        h[i]=a[i].x;
        a[i].id=i;
    }
    sort(h+1,h+n+1);
    k=unique(h+1,h+1+n)-h-1;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    dfs(1);
    dfs2(1,1);
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++)
    {
        sum[i]=sum[i-1]+v[q[i]];
    }
    for(int i=1;i<=n;i++)
    {
        int fx=lower_bound(h+1,h+1+k,a[i].x)-h;
        g[fx]=i;
        if(fx==(lower_bound(h+1,h+1+k,a[i-1].x)-h))
        {
            total[fx]=total[fx]+1ll*dep[a[i].id];
        }
        else
        {
            total[fx]=total[fx-1]+1ll*dep[a[i].id];
            root[fx]=root[fx-1];
        }
        updata(a[i].id,fx);
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&z,&x,&y);
        l=min((x+ans)%A,(y+ans)%A);
        r=max((x+ans)%A,(y+ans)%A);
        l=upper_bound(h+1,h+1+k,l-1)-h-1;
        r=upper_bound(h+1,h+1+k,r)-h-1;
        ans=total[r]-total[l]+1ll*(g[r]-g[l])*dep[z]-2*find(z,l,r);
        printf("%lld\n",ans);
    }
}