#include<bits/stdc++.h>
#define ls k<<1
#define rs k<<1|1
#define int long long
using namespace std;
inline int read(){
int x=0; char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x;
}
const int N=50000+1000;
struct TREE{
int l,r,sum,lazy;
}t[5*N];
int n,Th,tot,cnt;
int h[N],siz[N],son[N],dep[N],top[N],fa[N],dfn[N],ans[N];
struct edge{
int v,nxt;
}e[N+N];
void add(int u,int v){
e[++tot].v=v;
e[tot].nxt=h[u];
h[u]=tot;
}
void dfs1(int u){
siz[u]=1;
for(int i=h[u];i!=0;i=e[i].nxt){
int v=e[i].v;
if(v==fa[u]) continue ;
fa[v]=u;
dep[v]=dep[u]+1;
dfs1(v);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]]) son[u]=v;
}
}
void dfs2(int u,int topx){
dfn[u]=++cnt;
top[u]=topx;
if(!son[u]) return ;
dfs2(son[u],topx);
for(int i=h[u];i!=0;i=e[i].nxt){
int v=e[i].v;
if(v==fa[u]||v==son[u]) continue ;
dfs2(v,v);
}
}
struct Que{
int u,z,id,flag;
}q[N+N];
bool cmp(Que a,Que b){
return a.u<b.u;
}
void update(int k){
t[k].sum=t[ls].sum+t[rs].sum;
}
void build(int k,int l,int r){
t[k].l=l;
t[k].r=r;
if(l==r) return ;
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
update(k);
}
void pushdown(int k){
if(t[k].l==t[k].r){
t[k].lazy=0;
return ;
}
t[ls].sum+=(t[ls].r-t[ls].l+1)*t[k].lazy;
t[rs].sum+=(t[rs].r-t[rs].l+1)*t[k].lazy;
t[ls].lazy+=t[k].lazy;
t[rs].lazy+=t[k].lazy;
t[k].lazy=0;
update(k);
}
void change(int k,int l,int r,int val){
if(t[k].l==l&&t[k].r==r){
t[k].sum+=(t[k].r-t[k].l+1)*val;
t[k].lazy+=val;
return ;
}
pushdown(k);
int mid=(t[k].l+t[k].r)>>1;
if(r<=mid) change(ls,l,r,val);
else if(l>mid) change(rs,l,r,val);
else change(ls,l,mid,val),change(rs,mid+1,r,val);
update(k);
}
int query(int k,int l,int r){
if(t[k].l==l&&t[k].r==r){
return t[k].sum;
}
pushdown(k);
int mid=(t[k].l+t[k].r)>>1;
if(r<=mid) return query(ls,l,r);
else if(l>mid) return query(rs,l,r);
else return query(ls,l,mid)+query(rs,mid+1,r);
}
void k1(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]]) swap(x,y);
change(1,dfn[top[y]],dfn[y],1);
y=fa[top[y]];
}
change(1,min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),1);
}
int k2(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]]) swap(x,y);
ans=(ans+query(1,dfn[top[y]],dfn[y]));
y=fa[top[y]];
}
ans=(ans+query(1,min(dfn[x],dfn[y]),max(dfn[x],dfn[y])));
return ans;
}
signed main(){
n=read();Th=read();
for(int i=1;i<n;i++){
int u=read()+1;
add(u,i+1);
}
int now=0;
while(Th--){
int l=read()+1,r=read()+1,z=read()+1;
q[++now]=(Que){l-1,z,now,0};
q[++now]=(Que){r,z,now-1,1};
}
dfs1(1);
dfs2(1,1);
build(1,1,n);
sort(1+q,1+q+now,cmp);
int pre=1;
for(int i=1;i<=now;i++){
while(pre<=q[i].u) k1(1,pre),pre++;
int op=k2(1,q[i].z);
if(q[i].flag==0) ans[q[i].id]-=op;
else ans[q[i].id]+=op;
}
for(int i=1;i<=now;i+=2){
cout<<ans[i]%201314<<endl;
}
return 0;
}