#include <bits/stdc++.h>
#pragma GCC optimization("O3")
#pragma GCC optimization("unroll-loops")
using namespace std;
template <class T>
using vec = std::vector<T>;
template <class T>
using vec2d = std::vector<std::vector<T>>;
bool __hack = std::ios::sync_with_stdio(false);
auto __hack1 = cin.tie(nullptr);
struct Input {
  Input(istream& in) : in(&in) {}
  template <class T>
  T next() const {
    T x;
    *in >> x;
    return x;
  }
  int ni() const { return next<int>(); }
  template <class T>
  vec<T> nVec(int n) const {
    vec<T> v(n);
    for (int i = 0; i < n; ++i) {
      v[i] = next<T>();
    }
    return v;
  }
  vec<int> nvi(int n) const { return nVec<int>(n); }
  istream* in;
};
Input in(cin);
class Output {
 private:
  ostream* out;
  template <typename T>
  void printSingle(const T& value) {
    *out << value;
  }

 public:
  Output(ostream& out) : out(&out) {}
  inline void print() {}
  template <typename T, typename... Ts>
  inline void print(const T& f, const Ts&... args) {
    printSingle(f);
    if (sizeof...(args) != 0) {
      *out << ' ';
      print(args...);
    }
  }
  template <typename... Ts>
  inline void println(const Ts&... args) {
    print(args...);
    (*out) << '\n';
  }
  template <typename... Ts>
  inline void operator()(const Ts&... args) {
    println(args...);
  }
};
Output out(cout);
namespace template_util {
constexpr int bytecount(uint64_t x) { return x ? 1 + bytecount(x >> 8) : 0; }
template <int N>
struct bytetype {};
template <uint64_t N>
struct minimal_uint : bytetype<bytecount(N)> {};
}  // namespace template_util
void buildSimpleDfsOrder(const vec2d<int>& tree, vec<int>& height,
                         vec<int>& tIn, vec<int>& tOut, vec<int>& dfsOrder,
                         int root = 0) {
  int timer = 0;
  int n = static_cast<int>(tree.size());
  height = vector<int>(n, -1);
  dfsOrder.clear();
  dfsOrder.reserve(n);
  tIn = vector<int>(n, -1);
  tOut = vector<int>(n, -1);
  std::function<void(int, int)> dfs = [&](int v, int h) {
    height[v] = h;
    dfsOrder.push_back(v);
    tIn[v] = timer++;
    for (int to : tree[v]) {
      if (height[to] != -1) {
        continue;
      }
      dfs(to, h + 1);
    }
    tOut[v] = timer - 1;
  };
  dfs(root, 0);
}
const int MAXN = 50001;
int h[MAXN], na[MAXN], active[MAXN];
void solve(istream& inStream, ostream& outStream) {
  in = Input(inStream);
  out = Output(outStream);
  auto n = in.ni();
  auto q = in.ni();
  auto a = in.nvi(n);
  vec2d<int> g(n);
  for (int i = 0; i < (n - 1); ++i) {
    auto p = in.ni() - 1;
    g[p].push_back(i + 1);
  }
  vec<int> height, tIn, tOut, dfsOrder;
  buildSimpleDfsOrder(g, height, tIn, tOut, dfsOrder);
  for (int i = 0; i < (n); ++i) {
    h[i] = height[dfsOrder[i]];
    na[i] = a[dfsOrder[i]];
  }
  int sum, count, he, v, take;
  for (int t = 0; t < q; ++t) {
    v = in.ni() - 1;
    sum = count = 0;
    he = height[v];
    for (int i = tIn[v]; i <= tOut[v]; ++i) {
      take = (active[i] <= t);
      sum += take * h[i];
      count += take;
      active[i] = (1 - take) * active[i] + take * (t + na[i]);
    }
    out(sum - count * he, count);
  }
}
int main() {
  solve(cin, cout);
  return 0;
}
