#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
using namespace std;
const int N = 1e5 + 5;
vector<int> g[N];
int anc[N][20], deep[N], dfn[N], tot = 0;
struct node {
  int mx, mn, _mx, _mn;
  node operator^(const node& rhs) {
    node res = rhs;
    if (dfn[mx] >= dfn[res.mx]) {
      res._mx = res.mx;
      res.mx = mx;
    } else if (dfn[mx] > dfn[res._mx]) {
      res._mx = mx;
    }
    if (dfn[mn] <= dfn[res.mn]) {
      res._mn = res.mn;
      res.mn = mn;
    } else if (dfn[mn] < dfn[res._mn]) {
      res._mn = mn;
    }
    if (dfn[_mx] >= dfn[res.mx]) {
      res._mx = res.mx;
      res.mx = _mx;
    } else if (dfn[_mx] > dfn[res._mx]) {
      res._mx = _mx;
    }
    if (dfn[_mn] <= dfn[res.mn]) {
      res._mn = res.mn;
      res.mn = _mn;
    } else if (dfn[_mn] < dfn[res._mn]) {
      res._mn = _mn;
    }
    return res;
  }
} tree[N << 2];
void dfs(int u, int o) {
  anc[u][0] = o;
  for (int i = 1; i < 20; i++) anc[u][i] = anc[anc[u][i - 1]][i - 1];
  deep[u] = deep[o] + 1;
  dfn[u] = ++tot;
  for (int v : g[u]) {
    if (v != o) {
      dfs(v, u);
    }
  }
}
int lca(int u, int v) {
  if (deep[u] < deep[v]) swap(u, v);
  for (int i = 19; i >= 0; i--)
    if (deep[anc[u][i]] >= deep[v]) u = anc[u][i];
  if (u == v) return u;
  for (int i = 19; i >= 0; i--)
    if (anc[u][i] != anc[v][i]) u = anc[u][i], v = anc[v][i];
  return anc[u][0];
}
void push_up(int rt) { tree[rt] = tree[rt << 1] ^ tree[rt << 1 | 1]; }
void build(int rt, int l, int r) {
  if (l == r) {
    tree[rt] = node{l, l, 0, 100001};
    return;
  }
  int m = l + r >> 1;
  build(rt << 1, l, m);
  build(rt << 1 | 1, m + 1, r);
  push_up(rt);
}
node query(int L, int R, int rt, int l, int r) {
  if (L <= l && r <= R) return tree[rt];
  int m = l + r >> 1;
  node res = {0, 0, 0, 0};
  if (L <= m) res = query(L, R, rt << 1, l, m);
  if (R > m) {
    if (res.mn == 0)
      res = query(L, R, rt << 1 | 1, m + 1, r);
    else
      res = res ^ query(L, R, rt << 1 | 1, m + 1, r);
  }
  return res;
}
int main() {
  int n, p, q, l, r;
  scanf("%d %d", &n, &q);
  for (int i = 2; i <= n; i++) {
    scanf("%d", &p);
    g[p].push_back(i);
  }
  dfs(1, 1);
  dfn[100001] = 100001;
  build(1, 1, n);
  for (int i = 1; i <= q; i++) {
    scanf("%d %d", &l, &r);
    node tmp = query(l, r, 1, 1, n);
    int l1 = lca(tmp.mx, tmp._mn), l2 = lca(tmp._mx, tmp.mn);
    if (deep[l1] < deep[l2])
      printf("%d %d\n", tmp.mx, deep[l2] - 1);
    else
      printf("%d %d\n", tmp.mn, deep[l1] - 1);
  }
  return 0;
}
