#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<vector>
using namespace std;
const int maxn=5e4+10;
struct qr{
int u,v,ans;
}qrs[maxn],qrs2[maxn];
int qrcnt=0,qrcnt2=1;
vector<int> son[maxn];
bool ish[maxn];
int fa[maxn],depth[maxn],size[maxn],top[maxn],dfn[maxn],redfn[maxn],dfncnt=0;
long long val[maxn];
int hs[maxn],hv[maxn];
int n,m,r=1,mod=201314;
vector<int> to[maxn];
int grtotr_vis[maxn];
void addedge(int u,int v)
{
to[u].push_back(v);
to[v].push_back(u);
}
void inputs()
{
scanf("%d%d",&n,&m);
for(int i=2;i<=n;i++)
{
scanf("%d",&fa[i]);
fa[i]++;
son[fa[i]].push_back(i);
}
}
void dfs(int x,int dp)
{
depth[x]=dp;
size[x]=1;
for(int i=0;i<son[x].size();i++)
{
int s=son[x][i];
dfs(s,dp+1);
size[x]+=size[s];
if(size[s]>hv[x])
{
ish[hs[x]]=0;
ish[s]=1;
hs[x]=s;
hv[x]=size[s];
}
}
}
void dfs1(int x)
{
dfn[++dfncnt]=x;
if(ish[x])
{
top[x]=top[fa[x]];
}
else
{
top[x]=x;
}
if(hs[x]!=0)
{
dfs1(hs[x]);
for(int i=0;i<son[x].size();i++)
{
if(son[x][i]!=hs[x])
{
dfs1(son[x][i]);
}
}
}
}
long long a[maxn],sum_v[4*maxn],add_lazy[4*maxn];
void build(int p,int l,int r)
{
if(l==r)
{
sum_v[p]=0;
return ;
}
int mid=(l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
sum_v[p]=(sum_v[p*2]+sum_v[p*2+1])%mod;
}
void addf(int p,int l,int r,long long v)
{
add_lazy[p]=(add_lazy[p]+v)%mod;
sum_v[p]=(sum_v[p]+v*(r-l+1)%mod)%mod;
return ;
}
void pushdown(int p,int l,int r,int mid)
{
if(add_lazy[p]!=0)
{
addf(p*2,l,mid,add_lazy[p]);
addf(p*2+1,mid+1,r,add_lazy[p]);
add_lazy[p]=0;
}
}
void pluss(int p,int l,int r,int tl,int tr,long long v)
{
if(tl<=l && r<=tr) return addf(p,l,r,v);
int mid=(l+r)>>1;
pushdown(p,l,r,mid);
if(tl<=mid)
{
pluss(p*2,l,mid,tl,tr,v);
}
if(mid<tr)
{
pluss(p*2+1,mid+1,r,tl,tr,v);
}
sum_v[p]=(sum_v[p*2]+sum_v[p*2+1])%mod;
}
long long query(int p,int l,int r,int tl,int tr)
{
if(tl<=l && r<=tr) return sum_v[p];
int mid=(l+r)>>1;
long long ret=0;
pushdown(p,l,r,mid);
if(tl<=mid)
{
ret=(ret+query(p*2,l,mid,tl,tr))%mod;
}
if(mid<tr)
{
ret=(ret+query(p*2+1,mid+1,r,tl,tr))%mod;
}
return ret;
}
long long heavyquery(int x,int y)
{
if(depth[x]>depth[y])
{
int t=x;x=y;y=t;
}
return query(1,1,n,redfn[x],redfn[y]);
}
void heavyplus(int x,int y,long long v)
{
if(depth[x]>depth[y])
{
int t=x;x=y;y=t;
}
pluss(1,1,n,redfn[x],redfn[y],v);
}
long long pathquery(int x,int y)
{
long long ans=0;
while(top[x]!=top[y])
{
if(depth[top[x]]>=depth[top[y]])
{
ans=(ans+heavyquery(top[x],x))%mod;
x=top[x];
if(x!=r) x=fa[x];
}
else
{
ans=(ans+heavyquery(top[y],y))%mod;
y=top[y];
if(y!=r) y=fa[y];
}
}
ans=(ans+heavyquery(x,y))%mod;
return ans;
}
void pathplus(int x,int y,long long v)
{
while(top[x]!=top[y])
{
if(depth[top[x]]>=depth[top[y]])
{
heavyplus(top[x],x,v);
x=top[x];
if(x!=r) x=fa[x];
}
else
{
heavyplus(top[y],y,v);
y=top[y];
if(y!=r) y=fa[y];
}
}
heavyplus(x,y,v);
}
long long subquery(int x)
{
return query(1,1,n,redfn[x],redfn[x]+size[x]-1);
}
void subplus(int x,long long v)
{
pluss(1,1,n,redfn[x],redfn[x]+size[x]-1,v);
}
bool cmp(qr a,qr b)
{
if(a.u==b.u)
{
return a.v<=b.v;
}
return a.u<=b.u;
}
int search(int u,int v)
{
int l=1,r=qrcnt;
qr a;
a.u=u;
a.v=v;
while(l<r)
{
int mid=(l+r)>>1;
if(cmp(a,qrs[mid]))
{
r=mid;
}
else
{
l=mid+1;
}
}
return qrs[l].ans;
}
int main()
{
freopen("P4211_1.in","r",stdin);
freopen("P4211_1test.out","w",stdout);
inputs();
dfs(r,1);
dfs1(r);
for(int i=1;i<=n;i++)
{
redfn[dfn[i]]=i;
a[i]=val[dfn[i]];
}
build(1,1,n);
for(int i=1;i<=m;i++)
{
int l,r,z;
scanf("%d%d%d",&l,&r,&z);
if(l>r)
{
int t=l;l=r;r=t;
}
l++;r++;z++;
qrs2[i].u=l;
qrs2[i].v=r;
qrs2[i].ans=z;
qrs[++qrcnt].u=l-1;
qrs[qrcnt].v=z;
qrs[++qrcnt].u=r;
qrs[qrcnt].v=z;
}
sort(qrs+1,qrs+1+qrcnt,cmp);
for(int i=1;i<=qrs[qrcnt].u;i++)
{
pathplus(1,i,1);
while(qrs[qrcnt2].u<=i && qrcnt2<=qrcnt)
{
qrs[qrcnt2].ans=pathquery(1,qrs[qrcnt2].v);
qrcnt2++;
}
}
for(int i=1;i<=m;i++)
{
int l=qrs2[i].u,r=qrs2[i].v,z=qrs2[i].ans;
printf("%d\n",(search(r,z)-search(l-1,z)+mod)%mod);
}
return 0;
}