#include <bits/stdc++.h>
using namespace std;
struct SegmentTreeNode {
  int val;
  int lr, rr;
  SegmentTreeNode() { val = 0; }
};
void Set_Height(int curr, vector<vector<int> > &Edge, vector<bool> &visited,
                vector<int> &Height, int h);
void Flatten_Tree_Nodes(int curr, vector<vector<int> > &Edge,
                        vector<int> &Height, vector<bool> &visited,
                        vector<int> &EnterTime, vector<int> &ExitTime,
                        vector<int> &FlatTree, int &TimeCounter);
void Set_SegTree(int curr, vector<SegmentTreeNode> &SegTree, int l, int r,
                 vector<int> &Height);
int Range_Query(int curr, vector<SegmentTreeNode> &SegTree, int l, int r,
                vector<int> &Height);
int solve(vector<SegmentTreeNode> &SegTree, vector<int> &Height,
          vector<int> &EnterTime, int a, int b, int d);
int LCA(vector<SegmentTreeNode> &SegTree, vector<int> &Height,
        vector<int> &EnterTime, int u, int v);
int main() {
  int N, Q, q, i, pi, n, a, b, c, res;
  cin >> N >> Q;
  vector<vector<int> > Edge(N + 1, vector<int>(0));
  vector<int> Height(N + 1);
  for (i = 2; i <= N; i++) {
    cin >> pi;
    Edge[pi].push_back(i);
    Edge[i].push_back(pi);
  }
  vector<bool> visited(N + 1, false);
  Set_Height(1, Edge, visited, Height, 1);
  Height[0] = 1000000001;
  for (i = 1; i <= N; i++) visited[i] = false;
  vector<int> FlatTree(1, 0), EnterTime(N + 1), ExitTime(N + 1);
  int TimeCounter = 1;
  Flatten_Tree_Nodes(1, Edge, Height, visited, EnterTime, ExitTime, FlatTree,
                     TimeCounter);
  n = (int)pow(2, ceil(log2(FlatTree.size() - 1)));
  vector<SegmentTreeNode> SegTree(2 * n);
  for (i = 1; i < FlatTree.size(); i++) SegTree[n - 1 + i].val = FlatTree[i];
  Set_SegTree(1, SegTree, 1, n, Height);
  for (q = 0; q < Q; q++) {
    cin >> a >> b >> c;
    res = -1;
    res = max(res, solve(SegTree, Height, EnterTime, a, b, c));
    res = max(res, solve(SegTree, Height, EnterTime, a, c, b));
    res = max(res, solve(SegTree, Height, EnterTime, c, b, a));
    cout << res << '\n';
  }
  return 0;
}
int solve(vector<SegmentTreeNode> &SegTree, vector<int> &Height,
          vector<int> &EnterTime, int a, int b, int d) {
  int ab, ad, bd, l1, l2, l3, l;
  ab = LCA(SegTree, Height, EnterTime, a, b);
  ad = LCA(SegTree, Height, EnterTime, a, d);
  bd = LCA(SegTree, Height, EnterTime, b, d);
  l1 = abs(Height[a] - Height[ad]) + abs(Height[ad] - Height[d]);
  l2 = abs(Height[b] - Height[bd]) + abs(Height[bd] - Height[d]);
  l3 = abs(Height[a] - Height[ab]) + abs(Height[ab] - Height[b]);
  l = (l1 + l2 - l3) / 2;
  return l + 1;
}
int LCA(vector<SegmentTreeNode> &SegTree, vector<int> &Height,
        vector<int> &EnterTime, int u, int v) {
  int l, r, lca_node;
  l = EnterTime[u];
  r = EnterTime[v];
  if (l > r) swap(l, r);
  lca_node = Range_Query(1, SegTree, l, r, Height);
  return lca_node;
}
void Set_Height(int curr, vector<vector<int> > &Edge, vector<bool> &visited,
                vector<int> &Height, int h) {
  Height[curr] = h;
  visited[curr] = true;
  for (int i = 0; i < Edge[curr].size(); i++) {
    if (visited[Edge[curr][i]] == true) continue;
    Set_Height(Edge[curr][i], Edge, visited, Height, h + 1);
  }
  return;
}
void Flatten_Tree_Nodes(int curr, vector<vector<int> > &Edge,
                        vector<int> &Height, vector<bool> &visited,
                        vector<int> &EnterTime, vector<int> &ExitTime,
                        vector<int> &FlatTree, int &TimeCounter) {
  visited[curr] = true;
  EnterTime[curr] = TimeCounter;
  FlatTree.push_back(curr);
  for (int i = 0; i < Edge[curr].size(); i++) {
    if (visited[Edge[curr][i]] == true) continue;
    Flatten_Tree_Nodes(Edge[curr][i], Edge, Height, visited, EnterTime,
                       ExitTime, FlatTree, ++TimeCounter);
    FlatTree.push_back(curr);
  }
  TimeCounter++;
  ExitTime[curr] = TimeCounter;
  return;
}
void Set_SegTree(int curr, vector<SegmentTreeNode> &SegTree, int l, int r,
                 vector<int> &Height) {
  SegTree[curr].lr = l;
  SegTree[curr].rr = r;
  if (l == r) return;
  int N = r - l + 1;
  Set_SegTree(curr * 2, SegTree, l, l + N / 2 - 1, Height);
  Set_SegTree((curr << 1) + 1, SegTree, l + N / 2, r, Height);
  int h1, h2;
  if (Height[SegTree[curr << 1].val] < Height[SegTree[(curr << 1) + 1].val])
    SegTree[curr].val = SegTree[curr << 1].val;
  else
    SegTree[curr].val = SegTree[(curr << 1) + 1].val;
  return;
}
int Range_Query(int curr, vector<SegmentTreeNode> &SegTree, int l, int r,
                vector<int> &Height) {
  if (SegTree[curr].lr > r || SegTree[curr].rr < l)
    return 0;
  else if (SegTree[curr].lr >= l && SegTree[curr].rr <= r)
    return SegTree[curr].val;
  int n1, n2;
  n1 = Range_Query((curr << 1), SegTree, l, r, Height);
  n2 = Range_Query((curr << 1) + 1, SegTree, l, r, Height);
  if (Height[n1] < Height[n2])
    return n1;
  else
    return n2;
  return 0;
}
