#include using namespace std; #define all(x) begin(x), end(x) using ll = long long; using ld = long double; using pii = pair; using vi = vector; constexpr int MAXN = 1000006; constexpr int MOD = 11092019; int n; int val[MAXN]; int par[MAXN]; vi tree[MAXN]; // Everywhere in this problem, LIS means longest non decreasing subsequence // Data structure for saving partial LIS // Each level is a single layer in the patience sorting algorithm vector lis[MAXN]; // length of LIS ending at each node int dp[MAXN]; // number of ways to get to this node int ways[MAXN]; void dfs(int u) { /* cerr << "At node " << (u + 1) << '\n'; for (int i = 0; i <= max_lis; ++i) { for (auto& p : lis[i]) { cout << "{" << p.first << ", " << p.second << "}"; } cout << '\n'; } cout << '\n'; */ // Binary search to find LIS ending at this node int lo = 0; int hi = MAXN; while (lo + 1 < hi) { int mid = (lo + hi) / 2; if (!lis[mid].empty() and lis[mid].back().first <= val[u]) { lo = mid; } else { hi = mid; } } dp[u] = hi; ways[u] = lis[lo].back().second; // cout << "Node " << (u + 1) << " dp " << dp[u] << " " << ways[u] << '\n'; int lo2 = -1; int hi2 = lis[lo].size(); while (lo2 + 1 < hi2) { int mid2 = (lo2 + hi2) / 2; if (lis[lo][mid2].first > val[u]) { lo2 = mid2; } else { hi2 = mid2; } } if (lo2 >= 0) { ways[u] = (ways[u] + MOD - lis[lo][lo2].second) % MOD; } int prev_ways = lis[dp[u]].empty() ? 0 : lis[dp[u]].back().second; lis[dp[u]].emplace_back(val[u], (prev_ways + ways[u]) % MOD); for (int v : tree[u]) { dfs(v); } lis[dp[u]].pop_back(); } int main() { cin >> n; for (int i = 0; i < n; ++i) { cin >> val[i]; } for (int i = 1; i < n; ++i) { cin >> par[i]; --par[i]; tree[par[i]].push_back(i); } lis[0].emplace_back(-1, 1); dfs(0); int best_dp = 0; int best_ways = 0; for (int u = 0; u < n; ++u) { if (dp[u] > best_dp) { best_dp = dp[u]; best_ways = 0; } if (dp[u] == best_dp) { best_ways = (best_ways + ways[u]) % MOD; } } cout << best_dp << ' ' << best_ways << '\n'; return 0; }