#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 7;
const int maxk = 25;
const long long mod = 1e9 + 7;
const int inf = 1e9 + 7;
const long long linf = 1e17 + 7;
const double esp = 1e-7;
const double pi = acos(-1);
template <typename T>
inline void Read(T &first) {
  register char c;
  bool neg = false;
  for (c = getchar(); c < '0' || c > '9'; c = getchar())
    if (c == '-') neg = true;
  for (first = 0; c >= '0' && c <= '9'; c = getchar())
    first = first * 10 + c - '0';
  if (neg) first = -first;
}
template <typename T>
inline void Write(T first) {
  if (first < 0) putchar('-'), first = -first;
  if (first > 9) Write(first / 10);
  putchar(first % 10 + '0');
}
int n, q;
int nChain, chainHead[maxn], par[maxn], nChild[maxn], lv[maxn];
int in[maxn], inid[maxn], L[4 * maxn], R[4 * maxn];
vector<int> adj[maxn];
struct Neko {
  int mx1, mx2, mn1, mn2;
  friend inline Neko operator+(const Neko &A, const Neko &B) {
    vector<int> mx, mn;
    mx = {A.mx1, A.mx2, B.mx1, B.mx2};
    mn = {A.mn1, A.mn2, B.mn1, B.mn2};
    sort(mx.begin(), mx.end());
    sort(mn.begin(), mn.end());
    return {mx[3], mx[2], mn[0], mn[1]};
  }
} it[4 * maxn];
inline void Enter() {
  cin >> n >> q;
  for (int i = 2; i <= n; i++) {
    int p;
    cin >> p;
    adj[p].push_back(i);
    adj[i].push_back(p);
  }
}
inline void Dfs(const int &u, const int &p) {
  static int nVisit = 0;
  in[u] = ++nVisit;
  inid[nVisit] = u;
  par[u] = p;
  for (int v : adj[u])
    if (v != p) lv[v] = lv[u] + 1, Dfs(v, u), nChild[u] += nChild[v] + 1;
}
inline void Hld(const int &u) {
  if (!chainHead[u]) chainHead[u] = u;
  int specV = -1;
  for (int v : adj[u])
    if (v != par[u] && (specV == -1 || nChild[specV] < nChild[v])) specV = v;
  if (specV != -1) chainHead[specV] = chainHead[u], Hld(specV);
  for (int v : adj[u])
    if (v != par[u] && v != specV) nChain++, Hld(v);
}
inline int Lca(int u, int v) {
  while (chainHead[u] != chainHead[v]) {
    if (lv[chainHead[u]] < lv[chainHead[v]])
      v = par[chainHead[v]];
    else
      u = par[chainHead[u]];
  }
  return (lv[u] < lv[v]) ? u : v;
}
inline void Build(const int &first, const int &low, const int &high) {
  if (low > high) return;
  L[first] = low, R[first] = high;
  if (low == high) {
    it[first] = {in[low], -inf, in[low], inf};
    return;
  }
  int mid = (low + high) >> 1;
  Build(first << 1, low, mid);
  Build(first << 1 | 1, mid + 1, high);
  it[first] = it[first << 1] + it[first << 1 | 1];
}
inline Neko Query(const int &first, const int &low, const int &high) {
  if (L[first] > high || R[first] < low) return {-inf, -inf, inf, inf};
  if (low <= L[first] && R[first] <= high) return it[first];
  return Query(first << 1, low, high) + Query(first << 1 | 1, low, high);
}
inline void Init() {
  Dfs(1, -1);
  Hld(1);
  Build(1, 1, n);
}
inline void Solve() {
  while (q--) {
    int l, r;
    cin >> l >> r;
    Neko query = Query(1, l, r);
    int res = Lca(inid[query.mn1], inid[query.mx2]);
    int tmp = Lca(inid[query.mx1], inid[query.mn2]);
    int delV = inid[query.mx1];
    if (lv[res] < lv[tmp]) res = tmp, delV = inid[query.mn1];
    cout << delV << ' ' << lv[res] << '\n';
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL), cout.tie(NULL);
  Enter();
  Init();
  Solve();
  return 0;
}
