#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,avx,avx2")
#include <bits/stdc++.h>
using std::bitset;
using std::cout;
using std::deque;
using std::endl;
using std::greater;
using std::lower_bound;
using std::make_pair;
using std::map;
using std::max;
using std::min;
using std::multimap;
using std::multiset;
using std::nth_element;
using std::pair;
using std::priority_queue;
using std::queue;
using std::reverse;
using std::set;
using std::sort;
using std::sqrt;
using std::stable_sort;
using std::string;
using std::swap;
using std::unique;
using std::upper_bound;
using std::vector;
typedef int li;
typedef long double lf;
inline li read(){
int ans = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
f = (ch == '-') ? -1 : 1;
ch = getchar();
}
while(ch <= '9' && ch >= '0'){
ans = ans * 10 + (ch ^ 48);
ch = getchar();
}
return ans * f;
}
li n, m, rt;
vector<li> a[100010];
li dep[100010], lg[100010], fa[100010], dfn[100010], lendfn, pos[100010];
namespace LCA{
li st[100010][23];
void dfs(li u, li f){
fa[dfn[++lendfn] = u] = f;
pos[u] = lendfn;
dep[u] = dep[f] + 1;
for(li v : a[u]){
if(v == f) continue;
dfs(v, u);
}
}
void pre(li rt){
lg[0] = -1;
for(li i = 1; i <= n; i++) lg[i] = lg[i >> 1] + 1;
dfs(rt, 0);
for(li i = 1; i <= n; i++) st[i][0] = dfn[i];
for(li j = 1; j <= lg[n]; j++){
for(li i = 1; i + (1 << j) - 1 <= n; i++){
if(dep[st[i][j - 1]] < dep[st[i + (1 << (j - 1))][j - 1]]) st[i][j] = st[i][j - 1];
else st[i][j] = st[i + (1 << (j - 1))][j - 1];
}
}
}
li Lca(li u, li v){
if(u == v) return u;
if(pos[u] > pos[v]) swap(u, v);
li l = pos[u] + 1, r = pos[v];
li k = lg[r - l + 1];
if(dep[st[l][k]] > dep[st[r - (1 << k) + 1][k]]) return fa[st[r - (1 << k) + 1][k]];
return fa[st[l][k]];
}
}
using LCA::Lca;
// const li size_mo = 100;
li size_mo;
struct Query{
li l, r, x, id;
bool operator < (const Query b) const{
if(b.l / size_mo == l / size_mo){
if((b.l / size_mo) & 1) return r < b.r;
return r > b.r;
}
return l < b.l;
}
} q[1000010];
li ans[1000010], P[100010];
// set<li> V[100010];
struct BLOCK{
li a[100010], all;
const li size = 320;
li belong[100010], sum[100010], L[100010], R[100010];
void modify(li x, li add){
all += add;
a[x + 1] -= add;
sum[belong[x + 1]] -= add;
}
li query(li x){
li ans = all;
// for(li i = 1; i <= x; i++) ans += a[i];
for(li i = 1; i < belong[x]; i++) ans += sum[i];
for(li i = L[belong[x]]; i <= x; i++) ans += a[i];
return ans;
}
void init(){
for(li i = 1; i <= n; i++) belong[i] = i / size + 1, L[i] = 1e9, R[i] = 0;
for(li i = 1; i <= n; i++){
L[belong[i]] = min(L[belong[i]], i);
R[belong[i]] = max(R[belong[i]], i);
}
}
} tree;
struct DATA{
vector<li> pos, a;
li all, size;
li find_front(li x){
for(li i = x - 1; i; i--){
if(a[i]) return pos[i];
}
return -1;
}
li find_back(li x){
for(li i = x + 1; i <= size; i++){
if(a[i]) return pos[i];
}
return -1;
}
void insert(li x){
all++;
// cout << "ins " << x << endl;
a[x] = 1;
}
void erase(li x){
all--;
a[x] = 0;
}
} V[100010];
void add(li id){
// cout << "add " << id << "(" << P[id] << ", " << dep[id] << ")" << endl;
li maxn = dep[id] - 1;
if(V[dep[id]].all){
li it = V[dep[id]].find_front(P[id]);
// cout << it << " ";
if(it != -1){
li lca = Lca(id, it);
maxn = min(maxn, dep[id] - dep[lca] - 1);
}
it = V[dep[id]].find_back(P[id]);
// cout << it << endl;
if(it != -1){
li lca = Lca(id, it);
maxn = min(maxn, dep[id] - dep[lca] - 1);
}
}
// cout << dep[id] << " ins " << P[id] << endl;
V[dep[id]].insert(P[id]);
tree.modify(maxn, 1);
}
void del(li id){
// cout << "del " << id << endl;
li maxn = dep[id] - 1;
V[dep[id]].erase(P[id]);
if(V[dep[id]].all){
li it = V[dep[id]].find_front(P[id]);
if(it != -1){
li lca = Lca(id, it);
maxn = min(maxn, dep[id] - dep[lca] - 1);
}
it = V[dep[id]].find_back(P[id]);
if(it != -1){
li lca = Lca(id, it);
maxn = min(maxn, dep[id] - dep[lca] - 1);
}
}
tree.modify(maxn, -1);
}
int main(){
// freopen("wonderful.ans", "r", stdin);
// freopen("www.ww", "w", stdout);
n = read(), m = read();
size_mo = n / sqrt(m);
for(li i = 1; i <= n; i++){
a[fa[i] = read()].push_back(i);
if(fa[i] == 0) rt = i;
}
LCA::pre(rt);
for(li i = 1; i <= m; i++){
q[i].l = read(), q[i].r = read(), q[i].id = i, q[i].x = read();
}
sort(q + 1, q + 1 + m);
for(li yy = 1; yy <= n; yy++){
li i = dfn[yy];
V[dep[i]].size++;
};
for(li yy = 1; yy <= n; yy++){
li i = dfn[yy];
V[dep[i]].a.resize(V[dep[i]].size + 5);
V[dep[i]].pos.resize(V[dep[i]].size + 5);
V[dep[i]].size = 0;
};
for(li yy = 1; yy <= n; yy++){
li i = dfn[yy];
V[dep[i]].pos[P[i] = ++V[dep[i]].size] = i;
// cout << i << " " << P[i] << " " << V[dep[i]].pos[P[i]] << endl;
}
tree.init();
li l = q[1].l, r = q[1].l - 1;
for(li i = 1; i <= m; i++){
while(l > q[i].l) add(--l);
while(r < q[i].r) add(++r);
while(l < q[i].l) del(l++);
while(r > q[i].r) del(r--);
ans[q[i].id] = tree.query(q[i].x);
}
for(li i = 1; i <= m; i++){
printf("%d\n", ans[i]);
}
return 0;
}