#include<bits/stdc++.h>
using namespace std;
const int maxn = 1.5e5 + 10;
struct edge
{
int nxt,to,w;
}e[maxn << 1];
int head[maxn],tot;
void add_edge(int u,int v,int w)
{
e[++tot].nxt = head[u];
head[u] = tot;
e[tot].to = v;
e[tot].w = w;
}
int n,cnt;
int w[maxn];
bool cut[maxn];
int siz[maxn];
void dfs(int u,int fa)
{
siz[u] = 1;
for(int i = head[u];i;i = e[i].nxt)
{
int v = e[i].to;
if(v == fa || cut[v])continue;
dfs(v,u);
siz[u] += siz[v];
}
}
int miv,nrt;
void dfs2(int u,int fa)
{
int mxv = cnt - siz[u];
for(int i = head[u];i;i = e[i].nxt)
{
int v = e[i].to;
if(v == fa || cut[v])continue;
dfs(v,u);
mxv = max(mxv,siz[v]);
}
if(miv > mxv)
{
miv = mxv;
nrt = u;
}
}
struct node
{
int val;
long long ss,sv;
bool operator<(const node &p)const
{
return val < p.val;
}
};
vector<node> ans[maxn][3];
struct ed
{
int f;
long long dis;
int tp;
};
vector<ed> fa[maxn];
long long dep[maxn];
void dfs3(int u,int f,const int &g,const int &t)
{
fa[u].push_back({g,dep[u],t});
ans[g][t].push_back({w[u],1,dep[u]});
for(int i = head[u];i;i = e[i].nxt)
{
int v = e[i].to;
if(v == f || cut[v])continue;
dep[v] = dep[u] + e[i].w;
dfs3(v,u,g,t);
}
}
void solve(int u)
{
dfs(u,0);
if(siz[u] == 1)
{
cut[u] = 1;
fa[u].push_back({u,0,-1});
return ;
}
cnt = siz[u];
miv = 0x3f3f3f3f;
dfs2(u,0);
cut[nrt] = 1;
fa[nrt].push_back({nrt,0,-1});
for(int i = head[nrt],t = 0;i;i = e[i].nxt)
{
int v = e[i].to;
if(cut[v])continue;
dep[v] = e[i].w;
dfs3(v,u,nrt,t);
ans[nrt][t].push_back({0x3f3f3f3f,0,0});
sort(ans[nrt][t].begin(),ans[nrt][t].end());
for(int j = ans[nrt][t].size() - 2;j >= 0;j--)
{
ans[nrt][t][j].ss += ans[nrt][t][j + 1].ss;
ans[nrt][t][j].sv += ans[nrt][t][j + 1].sv;
}
t++;
}
for(int i = head[nrt];i;i = e[i].nxt)
{
int v = e[i].to;
if(!cut[v])solve(v);
}
}
long long res;
void query(int l,int r,int u)
{
res = 0;
vector<node>::iterator L;
vector<node>::iterator R;
for(int i = fa[u].size() - 1;i >= 0;i--)
{
int f = fa[u][i].f;
for(int tp = 0;tp <= 2;tp++)
{
if(tp == fa[u][i].tp || ans[f][tp].empty())continue;
L = lower_bound(ans[f][tp].begin(),ans[f][tp].end(),(node){l,0,0});
R = upper_bound(ans[f][tp].begin(),ans[f][tp].end(),(node){r,0,0});
res += fa[u][i].dis * (L -> ss - R -> ss) + L -> sv - R -> sv;
}
if(l <= w[f] && w[f] <= r)res += fa[u][i].dis;
}
}
int u,m;
long long l,r,A;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n >> m >> A;
for(int i = 1;i <= n;i++)cin >> w[i];
for(int i = 1;i < n;i++)
{
int u,v,w;
cin >> u >> v >> w;
add_edge(u,v,w);
add_edge(v,u,w);
}
solve(1);
for(int i = 1;i <= m;i++)
{
cin >> u >> l >> r;
l = (l + res) % A;
r = (r + res) % A;
if(l > r)swap(l,r);
query(l,r,u);
cout << res << '\n';
}
return 0;
}