#include #include #include #include int const MOD = 11092019; void dfs_iterative(std::vector> const &tree, std::vector const &label, std::vector *length, std::vector *multiplicity) { std::vector> stack = { {0, -1} }; std::vector>> longest = { { {-1, 1, 0 } } }; while (stack.size()) { auto [u, loc] = stack.back(); stack.pop_back(); auto u_lbl = label[u]; //std::cout << (u+1) << " " << loc << " " << u_lbl << "\n"; if (0 <= loc) { longest[loc].pop_back(); if (longest[loc].size() == 1) longest.pop_back(); } else { int x = longest.size(); while (u_lbl < std::get<0>(longest[x-1].back())) --x; length->at(u) = x; if (x == longest.size()) longest.push_back( { {-1, 1, 0 } } ); int y = longest[x-1].size(); while (1 < y and std::get<0>(longest[x-1][y-1]) <= u_lbl) --y; int m = 0; if (y + 1 < longest[x-1].size()) { auto b = std::get<2>(longest[x-1].back()); auto a = std::get<2>(longest[x-1][y-1]); m = (MOD + b - a) % MOD; } else { m = std::get<1>(longest[x-1].back()); } multiplicity->at(u) = m; longest[x].push_back({u_lbl, m, (std::get<2>(longest[x].back()) + m) % MOD}); stack.push_back({u, x}); for (auto v : tree[u]) stack.push_back({v, -1}); } } } int main() { int n; std::cin >> n; std::vector label(n), parent(n-1); for (auto &l : label) std::cin >> l; for (auto &p : parent) std::cin >> p, p--; // set up our DP structures std::vector length(n, 0); std::vector multiplicity(n, 0); std::vector> tree(n); for (int u = 1; u < n; ++u) tree[parent[u-1]].push_back(u); dfs_iterative(tree, label, &length, &multiplicity); int best = *std::max_element(length.begin(), length.end()); int count = 0; for (int i = 0; i < n; ++i) if (length[i] == best) count = (count + multiplicity[i]) % MOD; std::cout << best << " " << count << std::endl; /* for (auto x : length) { std::cerr << x << " "; } std::cerr << "\n"; for (auto x : multiplicity) { std::cerr << x << " "; } std::cerr << "\n"; */ return 0; }