Problem:
Fox Ciel is developing an artificial intelligence (AI) for a game. This game is described as a game tree T with n vertices.
Each node in the game has an evaluation value which shows how good a situation is.
This value is the same as maximum value of child nodes’ values multiplied by -1. Values on leaf nodes are evaluated with Ciel’s special function -- which is a bit heavy.
So, she will use alpha-beta pruning for getting root node’s evaluation value to decrease the number of leaf nodes to be calculated.
By the way, changing evaluation order of child nodes affects the number of calculation on the leaf nodes.
Therefore, Ciel wants to know the minimum and maximum number of times to calculate in leaf nodes when she could evaluate child node in arbitrary order.
She asked you to calculate minimum evaluation number of times and maximum evaluation number of times in leaf nodes.
Ciel uses following algotithm:
function negamax(node, α, β)
    if node is a terminal node
        return value of leaf node
    else
        foreach child of node
            val := -negamax(child, -β, -α)
            if val >= β
                return val
            if val > α
                α := val
        return α
[NOTE]
negamax algorithm
Input
Input follows following format:
n
p_1
p_2
...
p_n
k_1
t_{11}
t_{12}
...
t_{1k}
:
:
k_n
t_{n1}
t_{n2}
...
t_{nk}
The first line contains an integer
n
, which means the number of vertices in game tree T.
The second line contains
n
integers
p_i
, which means the evaluation value of vertex
i
.
Then, next
n
lines which contain the information of game tree T.
k_i
is the number of child nodes of vertex
i
, and
t_{ij}
is the indices of the child node of vertex
i
.
Input follows following constraints:
2 \leq n \leq 100
-10,000 \leq p_i \leq 10,000
0 \leq k_i \leq 5
2 \leq t_{ij} \leq n
Index of root node is
1
.
Evaluation value except leaf node is always
0
. This does not mean the evaluation values of non-leaf nodes are
0
. You have to calculate them if necessary.
Leaf node sometimes have evaluation value of
0
.
Game tree T is tree structure.
Output
Print the minimum evaluation number of times and the maximum evaluation number of times in leaf node.
Please separated by whitespace between minimum and maximum.
minimum maximum
Sample Input 1
3
0 1 1
2 2 3
0
0
Output for the Sample Input 1
2 2
Sample Input 2
8
0 0 100 100 0 -100 -100 -100
2 2 5
2 3 4
0
0
3 6 7 8
0
0
0
Output for the Sample Input 2
3 5
Sample Input 3
8
0 0 100 100 0 100 100 100
2 2 5
2 3 4
0
0
3 6 7 8
0
0
0
Output for the Sample Input 3
3 4
Sample Input 4
19
0 100 0 100 0 0 0 0 0 1 2 3 4 5 6 7 8 9 10
2 2 3
0
2 4 5
0
3 6 7 8
3 9 10 11
3 12 13 14
3 15 16 17
2 18 19
0
0
0
0
0
0
0
0
0
0
Output for the Sample Input 4
7 12

Submitted solutions:

code_snippet: // AOJ #2623 Optimal alpha beta pruning
// 2025.3.26

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
//	pc('\n');
}

const int NMAX = 205;
const int INF = 1 << 29;

int n;

int f(int x) {
    return (x < n ? x + n : x - n);
}

int p[NMAX];
vector<int> g[NMAX];

bool mem1[NMAX][NMAX][NMAX] = {false};
pair<int,int> dp1[NMAX][NMAX][NMAX];

bool mem2[NMAX][NMAX][NMAX] = {false};
pair<int,int> dp2[NMAX][NMAX][NMAX];

pair<int,int> solve1(int u, int a, int b) {
    if (mem1[u][a][b]) return dp1[u][a][b];
    if (g[u % n].empty()) return make_pair(1, u);

    vector<int> id = g[u % n];
    pair<int,int> best = make_pair(INF, INF);
    int init_a = a;
    do {
        a = init_a;
        int cnt = 0;
        bool finish = false;
        for (int to : id) {
            pair<int,int> res = solve1(to, f(b), f(a));
            res.second = f(res.second);
            cnt += res.first;
            if (p[res.second] >= p[b]) {
                if (best.first > cnt || (best.first == cnt && p[best.second] > p[res.second]))
                    best = make_pair(cnt, res.second);
                finish = true;
                break;
            }
            if (p[res.second] > p[a]) a = res.second;
        }
        if (finish) continue;
        if (best.first > cnt || (best.first == cnt && p[best.second] > p[a]))
            best = make_pair(cnt, a);
    } while (next_permutation(id.begin(), id.end()));
    a = init_a;
    mem1[u][a][b] = true;
    return dp1[u][a][b] = best;
}

pair<int,int> solve2(int u, int a, int b) {
    if (mem2[u][a][b]) return dp2[u][a][b];
    if (g[u % n].empty()) return make_pair(1, u);

    vector<int> id = g[u % n];
    pair<int,int> best = make_pair(-INF, INF);
    int init_a = a;
    do {
        a = init_a;
        int cnt = 0;
        bool finish = false;
        for (int to : id) {
            pair<int,int> res = solve2(to, f(b), f(a));
            res.second = f(res.second);
            cnt += res.first;
            if (p[res.second] >= p[b]) {
                if (best.first < cnt || (best.first == cnt && p[best.second] < p[res.second]))
                    best = make_pair(cnt, res.second);
                finish = true;
                break;
            }
            if (p[res.second] > p[a]) a = res.second;
        }
        if (finish) continue;
        if (best.first < cnt || (best.first == cnt && p[best.second] < p[a]))
            best = make_pair(cnt, a);
    } while (next_permutation(id.begin(), id.end()));
    a = init_a;
    mem2[u][a][b] = true;
    return dp2[u][a][b] = best;
}

int main() {
    n = Cin();
    for (int i = 0; i < n; i++) p[i] = Cin();
    p[n] = INF;

    for (int i = 0; i < n; i++) {
        int k = Cin();
        for (int j = 0; j < k; j++) {
            int t = Cin()-1;
            g[i].push_back(t);
        }
        sort(g[i].begin(), g[i].end());
    }

    n++;
    for (int i = n; i < 2 * n; i++) p[i] = p[i - n] * (-1);

    pair<int,int> ans = solve1(0, 2 * n - 1, n - 1);
    Cout(ans.first), pc(' ');
    ans = solve2(0, 2 * n - 1, n - 1);
    Cout(ans.first), pc('\n');
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 83284
final_rank: 14

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    int N;
    cin >> N;
    vector<int> A(N);
    rep(i,0,N) cin >> A[i];
    vector<vector<int>> G(N);
    rep(i,0,N) {
        int K;
        cin >> K;
        G[i].resize(K);
        rep(j,0,K) cin >> G[i][j], G[i][j]--;
    }
    vector<int> Eval(N);
    auto EvalDFS = [&](auto self, int V) -> int {
        if (G[V].empty()) return Eval[V] = A[V];
        Eval[V] = -inf;
        for (int NV : G[V]) {
            chmax(Eval[V], -self(self,NV));
        }
        return Eval[V];
    };
    EvalDFS(EvalDFS,0);
    map<tuple<int,int,int,int>,pair<int,int>> memo;
    auto DFS = [&](auto self, int V, int Alpha, int Beta, int mask) -> pair<int,int> {
        if (memo.count({V,Alpha,Beta,mask})) return memo[{V,Alpha,Beta,mask}];
        if (G[V].empty()) {
            return memo[{V,Alpha,Beta,mask}] = {1,1};
        }
        if (mask == (1<<(int)G[V].size())-1) return memo[{V,Alpha,Beta,mask}] = {0,0};
        int M = G[V].size();
        pair<int,int> Ret = {inf,-inf};
        rep(i,0,M) {
            if (mask & (1<<i)) continue;
            int NV = G[V][i];
            if (-Eval[NV] >= Beta) {
                auto Ret2 = self(self,NV,-Beta,-Alpha,0);
                Ret = {min(Ret.first, Ret2.first), max(Ret.second, Ret2.second)};
            }
            else if (-Eval[NV] > Alpha) {
                auto Ret2 = self(self,NV,-Beta,-Alpha,0);
                auto Ret3 = self(self,V,-Eval[NV], Beta, mask|(1<<i));
                Ret = {min(Ret.first, Ret2.first+Ret3.first), max(Ret.second, Ret2.second+Ret3.second)};
            }
            else {
                auto Ret2 = self(self,NV,-Beta,-Alpha,0);
                auto Ret3 = self(self,V,Alpha, Beta, mask|(1<<i));
                Ret = {min(Ret.first, Ret2.first+Ret3.first), max(Ret.second, Ret2.second+Ret3.second)};
            }
        }
        return memo[{V,Alpha,Beta,mask}] = Ret;
    };
    auto ANS = DFS(DFS,0,-inf,inf,0);
    cout << ANS.first << ' ' << ANS.second << endl;
}
accuracy: 1
time_ms: 140
memory_kb: 21284
final_rank: 6

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define eps 1e-9
#define INF 2000000000              // 2e9
#define LLINF 2000000000000000000ll // 2e18 (llmax:9e18)
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))

#define rep(i, x) for (int i = 0; i < (int)(x); i++)
#define drep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)

#define popcount __builtin_popcount
#define next __next
#define prev __prev

#ifndef LOCAL
#define dmp(...) ;
#else
#define dmp(...)                                                               \
  cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl
#endif

// ---------------- Utility ------------------

template <class T>
bool chmin(T &a, const T &b) {
  if (a <= b) return false;
  a = b;
  return true;
}

template <class T>
bool chmax(T &a, const T &b) {
  if (a >= b) return false;
  a = b;
  return true;
}

template <class T>
using MaxHeap = priority_queue<T>;

template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;

template <class T>
vector<T> vect(int len, T elem) {
  return vector<T>(len, elem);
}

// ----------------- Input -------------------

template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}

template <class T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) is >> vec[i];
  return is;
}

// ----------------- Output ------------------

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ',' << p.second;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &e : v) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const deque<T> &d) {
  for (const T &e : d) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const set<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  return os << "}";
}

template <class T, class U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << "{ ";
  for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) ";
  return os << "}";
}

template <class TupleTy, size_t... I>
void dump_tuple(ostream &os, const TupleTy t, std::index_sequence<I...>) {
  (..., (os << (I == 0 ? "" : ",") << std::get<I>(t)));
}

template <class... Args>
ostream &operator<<(ostream &os, const tuple<Args...> &t) {
  os << "(";
  dump_tuple(os, t, std::make_index_sequence<sizeof...(Args)>());
  return os << ")";
}

void dump_str_rec(ostringstream &) {}

template <class Head, class... Tail>
void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << ", " << head;
  dump_str_rec(oss, forward<Tail>(tail)...);
}

template <class T, class... U>
string dump_str(T &&arg, U &&... args) {
  ostringstream oss;
  oss << arg;
  dump_str_rec(oss, forward<U>(args)...);
  return oss.str();
}

// --------------- Fast I/O ------------------

void fastio() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
}

// ------------------ ACL --------------------

// #include <atcoder/modint>
// constexpr int MOD = 998244353;
// constexpr int MOD = 1000000007;
// using mint = atcoder::static_modint<MOD>;
// ostream &operator<<(ostream &os, const mint &v) {
//   return os << v.val();
// }

// ------------ End of template --------------

#define endl "\n"
using ll = long long;
using pii = pair<int, int>;

const bool multitest = false;

void solve() {
  int n;
  cin >> n;
  vector<int> p(n);
  cin >> p;

  vector<vector<int>> g(n);
  for (int i = 0; i < n; i++) {
    int k;
    cin >> k;
    for (int j = 0; j < k; j++) {
      int v;
      cin >> v;
      v--;
      g[i].push_back(v);
    }
  }

  vector<int> zip;
  for (int i = 0; i < n; i++) {
    if (g[i].size() == 0) {
      zip.push_back(p[i]);
      zip.push_back(-p[i]);
    }
  }
  zip.push_back(-INF);
  zip.push_back(INF);
  sort(all(zip));
  zip.erase(unique(all(zip)), zip.end());

  for (int i = 0; i < n; i++) {
    if (g[i].size() == 0) {
      p[i] = lower_bound(all(zip), p[i]) - zip.begin();
    } else {
      p[i] = -1;
    }
  }

  int m = zip.size();

  vector<int> negate(m);
  for (int i = 0; i < m; i++) {
    negate[i] = lower_bound(all(zip), -zip[i]) - zip.begin();
  }

  vector<int> eval(n, -INF);
  {
    function<void(int)> dfs = [&](int v) {
      if (g[v].size() == 0) {
        assert(p[v] >= 0);
        eval[v] = p[v];
        return;
      }
      for (int u : g[v]) {
        dfs(u);
        chmax(eval[v], negate[eval[u]]);
      }
      return;
    };
    dfs(0);
  }

  dmp(zip);
  dmp(p);
  dmp(eval);

  auto mx_neg_eval = vect(n, vect((1 << 5), 0));
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < (1 << g[i].size()); j++) {
      for (int k = 0; k < g[i].size(); k++) {
        int u = g[i][k];
        if ((j >> k) & 1) { chmax(mx_neg_eval[i][j], negate[eval[u]]); }
      }
    }
  }

  using Int = int8_t;

  {
    auto dp_min = vect(n, vect(m, vect(m, vect((1 << 5), (Int)(n + 1)))));
    // 残りS
    function<Int(int, int, int, int)> rec_min = [&](int v, int alpha, int beta,
                                                    int S) {
      Int &res = dp_min[v][alpha][beta][S];
      if (res != n + 1) return res;

      if (g[v].size() == 0) {
        assert(S == 0);
        return res = 1;
      }
      if (S == 0) return res = 0;

      int used = (1 << g[v].size()) - 1 - S;

      for (int k = 0; k < g[v].size(); k++) {
        if ((S >> k) & 1) {
          int u = g[v][k];
          int cur_alpha = max(alpha, mx_neg_eval[v][used]);
          if (negate[eval[u]] >= beta) {
            chmin(res, rec_min(u, negate[beta], negate[cur_alpha],
                               ((1 << g[u].size()) - 1)));
          } else {
            chmin(res, (Int)(rec_min(v, alpha, beta, S ^ (1 << k)) +
                             rec_min(u, negate[beta], negate[cur_alpha],
                                     ((1 << g[u].size()) - 1))));
          }
        }
      }
      return res;
    };
    cout << (int)rec_min(0, 0, m - 1, (1 << g[0].size()) - 1) << ' ';
  }

  {
    auto dp_max = vect(n, vect(m, vect(m, vect((1 << 5), (Int)(-1)))));

    // 残りS
    function<Int(int, int, int, int)> rec_max = [&](int v, int alpha, int beta,
                                                    int S) {
      Int &res = dp_max[v][alpha][beta][S];
      if (res != -1) return res;

      if (g[v].size() == 0) {
        assert(S == 0);
        return res = 1;
      }
      if (S == 0) return res = 0;

      int used = (1 << g[v].size()) - 1 - S;

      for (int k = 0; k < g[v].size(); k++) {
        if ((S >> k) & 1) {
          int u = g[v][k];
          int cur_alpha = max(alpha, mx_neg_eval[v][used]);
          if (negate[eval[u]] >= beta) {
            chmax(res, rec_max(u, negate[beta], negate[cur_alpha],
                               ((1 << g[u].size()) - 1)));
          } else {
            chmax(res, (Int)(rec_max(v, alpha, beta, S ^ (1 << k)) +
                             rec_max(u, negate[beta], negate[cur_alpha],
                                     ((1 << g[u].size()) - 1))));
          }
        }
      }
      return res;
    };

    cout << (int)rec_max(0, 0, m - 1, (1 << g[0].size()) - 1) << endl;
  }

  return;
}

int main() {
  fastio();
  if (!multitest) {
    solve();
  } else {
    cerr << "[Warning] Multi testcase mode on" << endl;
    int t;
    cin >> t;
    while (t--) solve();
  }
  return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 190456
final_rank: 18

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define eps 1e-9
#define INF 2000000000              // 2e9
#define LLINF 2000000000000000000ll // 2e18 (llmax:9e18)
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))

#define rep(i, x) for (int i = 0; i < (int)(x); i++)
#define drep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)

#define popcount __builtin_popcount
#define next __next
#define prev __prev

#ifndef LOCAL
#define dmp(...) ;
#else
#define dmp(...)                                                               \
  cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl
#endif

// ---------------- Utility ------------------

template <class T>
bool chmin(T &a, const T &b) {
  if (a <= b) return false;
  a = b;
  return true;
}

template <class T>
bool chmax(T &a, const T &b) {
  if (a >= b) return false;
  a = b;
  return true;
}

template <class T>
using MaxHeap = priority_queue<T>;

template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;

template <class T>
vector<T> vect(int len, T elem) {
  return vector<T>(len, elem);
}

// ----------------- Input -------------------

template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}

template <class T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) is >> vec[i];
  return is;
}

// ----------------- Output ------------------

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ',' << p.second;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &e : v) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const deque<T> &d) {
  for (const T &e : d) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const set<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  return os << "}";
}

template <class T, class U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << "{ ";
  for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) ";
  return os << "}";
}

template <class TupleTy, size_t... I>
void dump_tuple(ostream &os, const TupleTy t, std::index_sequence<I...>) {
  (..., (os << (I == 0 ? "" : ",") << std::get<I>(t)));
}

template <class... Args>
ostream &operator<<(ostream &os, const tuple<Args...> &t) {
  os << "(";
  dump_tuple(os, t, std::make_index_sequence<sizeof...(Args)>());
  return os << ")";
}

void dump_str_rec(ostringstream &) {}

template <class Head, class... Tail>
void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << ", " << head;
  dump_str_rec(oss, forward<Tail>(tail)...);
}

template <class T, class... U>
string dump_str(T &&arg, U &&... args) {
  ostringstream oss;
  oss << arg;
  dump_str_rec(oss, forward<U>(args)...);
  return oss.str();
}

// --------------- Fast I/O ------------------

void fastio() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
}

// ------------------ ACL --------------------

// #include <atcoder/modint>
// constexpr int MOD = 998244353;
// constexpr int MOD = 1000000007;
// using mint = atcoder::static_modint<MOD>;
// ostream &operator<<(ostream &os, const mint &v) {
//   return os << v.val();
// }

// ------------ End of template --------------

#define endl "\n"
using ll = long long;
using pii = pair<int, int>;

const bool multitest = false;

void solve() {
  int n;
  cin >> n;
  vector<int> p(n);
  cin >> p;

  vector<vector<int>> g(n);
  for (int i = 0; i < n; i++) {
    int k;
    cin >> k;
    for (int j = 0; j < k; j++) {
      int v;
      cin >> v;
      v--;
      g[i].push_back(v);
    }
  }

  vector<int> zip;
  for (int i = 0; i < n; i++) {
    if (g[i].size() == 0) {
      zip.push_back(p[i]);
      zip.push_back(-p[i]);
    }
  }
  zip.push_back(-INF);
  zip.push_back(INF);
  sort(all(zip));
  zip.erase(unique(all(zip)), zip.end());

  for (int i = 0; i < n; i++) {
    if (g[i].size() == 0) {
      p[i] = lower_bound(all(zip), p[i]) - zip.begin();
    } else {
      p[i] = -1;
    }
  }

  int m = zip.size();

  vector<int> negate(m);
  for (int i = 0; i < m; i++) {
    negate[i] = lower_bound(all(zip), -zip[i]) - zip.begin();
  }

  vector<int> eval(n, -INF);
  {
    function<void(int)> dfs = [&](int v) {
      if (g[v].size() == 0) {
        assert(p[v] >= 0);
        eval[v] = p[v];
        return;
      }
      for (int u : g[v]) {
        dfs(u);
        chmax(eval[v], negate[eval[u]]);
      }
      return;
    };
    dfs(0);
  }

  dmp(zip);
  dmp(p);
  dmp(eval);

  auto mx_neg_eval = vect(n, vect((1 << 5), 0));
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < (1 << g[i].size()); j++) {
      for (int k = 0; k < g[i].size(); k++) {
        int u = g[i][k];
        if ((j >> k) & 1) { chmax(mx_neg_eval[i][j], negate[eval[u]]); }
      }
    }
  }

  using Int = int8_t;

  {
    auto dp_min = vect(n, vect(m, vect(m, vect((1 << 5), (Int)(n + 1)))));
    // 残りS
    function<Int(int, int, int, int)> rec_min = [&](int v, int alpha, int beta,
                                                    int S) {
      Int &res = dp_min[v][alpha][beta][S];
      if (res != n + 1) return res;

      if (g[v].size() == 0) {
        assert(S == 0);
        return res = 1;
      }
      if (S == 0) return res = 0;

      int used = (1 << g[v].size()) - 1 - S;

      for (int k = 0; k < g[v].size(); k++) {
        if ((S >> k) & 1) {
          int u = g[v][k];
          int cur_alpha = max(alpha, mx_neg_eval[v][used]);
          if (negate[eval[u]] >= beta) {
            chmin(res, rec_min(u, negate[beta], negate[cur_alpha],
                               ((1 << g[u].size()) - 1)));
          } else {
            chmin(res, (Int)(rec_min(v, alpha, beta, S ^ (1 << k)) +
                             rec_min(u, negate[beta], negate[cur_alpha],
                                     ((1 << g[u].size()) - 1))));
          }
        }
      }
      return res;
    };
    cout << (int)rec_min(0, 0, m - 1, (1 << g[0].size()) - 1) << ' ';
  }

  {
    auto dp_max = vect(n, vect(m, vect(m, vect((1 << 5), (int8_t)(-1)))));

    // 残りS
    function<Int(int, int, int, int)> rec_max = [&](int v, int alpha, int beta,
                                                    int S) {
      Int &res = dp_max[v][alpha][beta][S];
      if (res != -1) return res;

      if (g[v].size() == 0) {
        assert(S == 0);
        return res = 1;
      }
      if (S == 0) return res = 0;

      int used = (1 << g[v].size()) - 1 - S;

      for (int k = 0; k < g[v].size(); k++) {
        if ((S >> k) & 1) {
          int u = g[v][k];
          int cur_alpha = max(alpha, mx_neg_eval[v][used]);
          if (negate[eval[u]] >= beta) {
            chmax(res, rec_max(u, negate[beta], negate[cur_alpha],
                               ((1 << g[u].size()) - 1)));
          } else {
            chmax(res, (Int)(rec_max(v, alpha, beta, S ^ (1 << k)) +
                             rec_max(u, negate[beta], negate[cur_alpha],
                                     ((1 << g[u].size()) - 1))));
          }
        }
      }
      return res;
    };

    cout << (int)rec_max(0, 0, m - 1, (1 << g[0].size()) - 1) << endl;
  }

  return;
}

int main() {
  fastio();
  if (!multitest) {
    solve();
  } else {
    cerr << "[Warning] Multi testcase mode on" << endl;
    int t;
    cin >> t;
    while (t--) solve();
  }
  return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 190472
final_rank: 19

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <map>

using namespace std;

constexpr int INF = 1 << 30;

void solve() {
    int n;
    cin >> n;

    vector<int> ps(n);
    for (auto& p : ps) cin >> p;

    vector<vector<int>> graph(n);
    for (int v = 0; v < n; ++v) {
        int k;
        cin >> k;
        graph[v].resize(k);

        for (auto& u : graph[v]) {
            cin >> u;
            --u;
        }
    }

    auto dps = vector(n, map<pair<int, int>, pair<int, int>>());
    vector<int> vals(n, -INF);

    auto dfs = [&](auto&& f, int v, int a, int b) -> pair<int, int> {
        auto& chs = graph[v];
        if (chs.empty()) {
            vals[v] = ps[v];
            return {1, 1};
        }

        auto& dp = dps[v];
        if (dp.count({a, b})) return dp[{a, b}];

        auto& [mi, ma] = dp[{a, b}];
        mi = INF, ma = -INF;

        sort(chs.begin(), chs.end());
        do {
            int cur_a = a;
            int cur_mi = 0, cur_ma = 0;

            for (auto c : chs) {
                auto [ch_mi, ch_ma] = f(f, c, -b, -cur_a);
                cur_mi += ch_mi, cur_ma += ch_ma;

                auto ch_val = -vals[c];
                if (ch_val >= b) break;
                cur_a = max(cur_a, ch_val);
            }

            mi = min(mi, cur_mi);
            ma = max(ma, cur_ma);
        } while (next_permutation(chs.begin(), chs.end()));

        for (auto c : chs) vals[v] = max(vals[v], -vals[c]);

        return {mi, ma};
    };

    auto [mi, ma] = dfs(dfs, 0, -INF, INF);
    cout << mi << " " << ma << "\n";
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 4072
final_rank: 1

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<deque>
#include<iomanip>
#include<tuple>
#include<cassert>
#include<set>
#include<complex>
#include<numeric>
#include<functional>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long int LL;
typedef pair<int,int> P;
typedef pair<LL,LL> LP;
const int INF=1<<30;
const LL MAX=1e9+7;

void array_show(int *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%d%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(LL *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%lld%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(vector<int> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%d%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
void array_show(vector<LL> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%lld%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
template<typename T> ostream& operator<<(ostream& os,const vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++){
        if(i)os<<" ";
        os<<v1[i];
    }
    return os;
}
template<typename T1,typename T2> ostream& operator<<(ostream& os,const pair<T1,T2>& p){
    os<<p.first<<" "<<p.second;
    return os;
}
template<typename T> istream& operator>>(istream& is,vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++)is>>v1[i];
    return is;
}
template<typename T1,typename T2> istream& operator>>(istream& is,pair<T1,T2>& p){
    is>>p.first>>p.second;
    return is;
}

namespace sol{
    typedef tuple<int,int,int> T;
    vector<int> val;
    vector<vector<int>> path;
    map<T,P> m1;

    P dfs(int pos,int al,int be);

    void setp(P& p1,P p2){
        p1.first=min(p1.first,p2.first);
        p1.second=max(p1.second,p2.second);
    }

    void addp(P& p1,P p2){
        p1.first+=p2.first;
        p1.second+=p2.second;
    }

    P dfs2(int pos,int al,int be,int used,int n){
        int i,j;
        int to;
        P pa,ps={INF,-INF};
        if(__builtin_popcount(used)==n)return {0,0};
        for(i=0;i<n;i++){
            if(used&1<<i)continue;
            to=path[pos][i];
            pa=dfs(to,-be,-al);
            if(-val[to]<be)addp(pa,dfs2(pos,max(al,-val[to]),be,used|1<<i,n));
            setp(ps,pa);
        }
        return ps;
    }

    P dfs(int pos,int al,int be){
        auto itr=m1.find({pos,al,be});
        if(itr!=m1.end())return itr->second;
        if(path[pos].empty())return {1,1};
        int n=path[pos].size();
        P pa=dfs2(pos,al,be,0,n);
        m1[{pos,al,be}]=pa;
        return pa;
    }

    int negmax(int pos){
        if(path[pos].empty())return val[pos];
        val[pos]=-INF;
        for(auto to:path[pos]){
            val[pos]=max(val[pos],-negmax(to));
        }
        return val[pos];
    }

    void solve(){
        int n,m;
        int i,j,k;
        int a,b,c;
        cin>>n;
        val.resize(n);
        path.resize(n);
        cin>>val;
        for(i=0;i<n;i++){
            cin>>a;
            for(j=0;j<a;j++){
                cin>>b;
                b--;
                path[i].push_back(b);
            }
        }
        negmax(0);
        cout<<dfs(0,-INF,INF)<<endl;
    }
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    sol::solve();
}
accuracy: 1
time_ms: 60
memory_kb: 4020
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=1000000007,MAX=205,INF=1<<29;

int N;

int f(int x){
    if(x<N) return x+N;
    else return x-N;
}

int P[MAX];

vector<int> G[MAX];
bool seemi[MAX][MAX][MAX],seema[MAX][MAX][MAX];
pair<int,int> mi[MAX][MAX][MAX],ma[MAX][MAX][MAX];

pair<int,int> solve1(int u,int a,int b){
    if(seemi[u][a][b]) return mi[u][a][b];
    if(si(G[u%N])==0) return mp(1,u);
    vector<int> id=G[u%N];
    pair<int,int> remi=mp(INF,INF);
    int savea=a;
    do{
        a=savea;
        int cnt=0;
        bool done=false;
        for(int to:id){
            auto res=solve1(to,f(b),f(a));
            res.se=f(res.se);
            cnt+=res.fi;
            if(P[res.se]>=P[b]){
                if(remi.fi>cnt) remi=mp(cnt,res.se);
                else if(remi.fi==cnt&&P[remi.se]>P[res.se]) remi=mp(cnt,res.se);
                done=true;
                break;
            }
            if(P[res.se]>P[a]){
                a=res.se;
            }
        }
        if(done) continue;
        
        if(remi.fi>cnt) remi=mp(cnt,a);
        else if(remi.fi==cnt&&P[remi.se]>P[a]) remi=mp(cnt,a);
    }while(next_permutation(all(id)));
    
    a=savea;
    seemi[u][a][b]=true;
    return mi[u][a][b]=remi;
}

pair<int,int> solve2(int u,int a,int b){
    if(seema[u][a][b]) return ma[u][a][b];
    if(si(G[u%N])==0) return mp(1,u);
    vector<int> id=G[u%N];
    pair<int,int> rema=mp(-INF,INF);
    int savea=a;
    do{
        a=savea;
        int cnt=0;
        bool done=false;
        for(int to:id){
            auto res=solve2(to,f(b),f(a));
            res.se=f(res.se);
            cnt+=res.fi;
            if(P[res.se]>=P[b]){
                if(rema.fi<cnt) rema=mp(cnt,res.se);
                else if(rema.fi==cnt&&P[rema.se]<P[res.se]) rema=mp(cnt,res.se);
                done=true;
                break;
            }
            if(P[res.se]>P[a]){
                a=res.se;
            }
        }
        if(done) continue;
        
        if(rema.fi<cnt) rema=mp(cnt,a);
        else if(rema.fi==cnt&&P[rema.se]<P[a]) rema=mp(cnt,a);
    }while(next_permutation(all(id)));
    
    a=savea;
    seema[u][a][b]=true;
    return ma[u][a][b]=rema;
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    cin>>N;
    for(int i=0;i<N;i++) cin>>P[i];
    P[N]=INF;
    
    for(int i=0;i<N;i++){
        int K;cin>>K;
        for(int j=0;j<K;j++){
            int x;cin>>x;x--;
            G[i].push_back(x);
        }
        sort(all(G[i]));
    }
    N++;
    for(int i=N;i<2*N;i++) P[i]=P[i-N]*(-1);
    cout<<solve1(0,2*N-1,N-1).fi<<" "<<solve2(0,2*N-1,N-1).fi<<endl;
}
accuracy: 1
time_ms: 50
memory_kb: 81404
final_rank: 13

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 2;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}


bool chked[100][205][205];
pair<P,int> memo[100][205][205];
void solve() {
	int n; cin >> n;
	vector<int> p(n);
	rep(i, n)cin >> p[i];
	vector<vector<int>> G(n);
	mt19937 mt(time(0));
	rep(i, n) {
		int len; cin >> len;
		G[i].resize(len);
		rep(j, len) {
			cin >> G[i][j]; G[i][j]--;
		}
		/*if (len > 0) {
			uniform_int_distribution<> ud(0, len - 1);
			rep(aa, 100) {
				int l = ud(mt);
				int r = ud(mt);
				swap(G[i][l], G[i][r]);
			}
		}*/
	}
	vector<int> score(n);
	per(i, n) {
		if (G[i].empty())score[i] = p[i];
		else {
			int ma = -mod;
			for (int to : G[i]) {
				ma = max(ma, -score[to]);
			}
			score[i] = ma;
		}
	}
	vector<int> vals;
	rep(i, n) {
		vals.push_back(p[i]);
		vals.push_back(-p[i]);
	}
	vals.push_back(-mod); vals.push_back(mod);
	sort(all(vals));
	vals.erase(unique(all(vals)), vals.end());
	vector<int> rev(vals.size());
	rep(i, vals.size()) {
		rev[i] = vals.size() - 1 - i;
	}
	rep(i, n) {
		score[i] = lower_bound(all(vals), score[i]) - vals.begin();
	}
	function<pair<P,int>(int,int,int)> dfs = [&](int id, int a, int b)->pair<P,int> {
		if (chked[id][a][b])return memo[id][a][b];
		chked[id][a][b] = true;
		if (G[id].empty()) {
			return memo[id][a][b] = { {1,1},score[id] };
		}
		else {
			int len = G[id].size();
			vector<int> v(len);
			rep(i, len)v[i] = i;
			P res = { mod,-mod };
			int res2 = a;
			do {
				P ad = { 0,0 };
				int ca = a, cb = b;
				rep(i, len) {
					int to = G[id][v[i]];
					pair<P, int> nexp = dfs(to, rev[cb], rev[ca]);
					P nex = nexp.first;
					res2 = max(res2, rev[nexp.second]);
					ad.first += nex.first;
					ad.second += nex.second;
					int val = rev[nexp.second];
					if (val >= cb)break;
					if (val > ca)ca = val;
				}
				//cout << "!?!? " << ad.first << "\n";
				res.first = min(res.first, ad.first);
				res.second = max(res.second, ad.second);
			} while (next_permutation(all(v)));
			return memo[id][a][b] = { res,res2 };
		}
	};
	P ans = dfs(0, 0, vals.size()-1).first;
	cout << ans.first << " " << ans.second << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//init_f();
	//init();
	//expr();
	//int t; cin >> t;rep(i,t)
	solve();
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 54756
final_rank: 8

code_snippet: #include<deque>
#include<queue>
#include<vector>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
#include<tuple>
#include<string>
#include<chrono>
#include<functional>
#include<iterator>
#include<random>
#include<unordered_set>
#include<array>
#include<map>
#include<iomanip>
#include<assert.h>
#include<list>
#include<bitset>
#include<stack>
#include<memory>
#include<numeric>
using namespace std;
using namespace std::chrono;
typedef long long int llint;
typedef long double lldo;
#define mp make_pair
#define mt make_tuple
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define fir first
#define sec second
#define res resize
#define ins insert
#define era erase
/*cout<<fixed<<setprecision(20);cin.tie(0);ios::sync_with_stdio(false);*/
const int mod=998244353 ;
const llint big=2.19e15+1;
const long double pai=3.141592653589793238462643383279502884197;
const long double eps=1e-10;
template <class T,class U>bool mineq(T& a,U b){if(a>b){a=b;return true;}return false;}
template <class T,class U>bool maxeq(T& a,U b){if(a<b){a=b;return true;}return false;}
llint gcd(llint a,llint b){if(a%b==0){return b;}else return gcd(b,a%b);}
llint lcm(llint a,llint b){if(a==0){return b;}return a/gcd(a,b)*b;}
template<class T> void SO(T& ve){sort(ve.begin(),ve.end());}
template<class T> void REV(T& ve){reverse(ve.begin(),ve.end());}
template<class T>llint LBI(const vector<T>&ar,T in){return lower_bound(ar.begin(),ar.end(),in)-ar.begin();}
template<class T>llint UBI(const vector<T>&ar,T in){return upper_bound(ar.begin(),ar.end(),in)-ar.begin();}
//結局、メモ化すれば大丈夫
vector<vector<int>>ko;
vector<int>p;
map<tuple<int,int,int>,tuple<int,int,int>>memo;
tuple<int,int,int> solve(int ter,int A,int B){
	if(ko[ter].size()==0){return mt(p[ter],1,1);}
	if(memo.count(mt(ter,A,B))){return memo[mt(ter,A,B)];}
	SO(ko[ter]);
	int syo=mod,dai=0;
	int ret=-mod;
	do{
		int nA=A;
		int gs=0,gd=0;
		for(auto it:ko[ter]){
			int val,ss,sd;
			tie(val,ss,sd)=solve(it,-B,-nA);
			gs+=ss;gd+=sd;val*=-1;
			if(val>=B){nA=val;break;}
			maxeq(nA,val);
		}
		//if(ret!=nA&&ret!=-mod&&nA<B){cerr<<"bag"<<ret<<" "<<ter<<endl;}
		ret=nA;
		mineq(syo,gs);
		maxeq(dai,gd);
	}while(next_permutation(ko[ter].begin(),ko[ter].end()));
	memo[mt(ter,A,B)]=mt(ret,syo,dai);
	return mt(ret,syo,dai);
}
int main(void){
	int n,i,j;cin>>n;
	p.res(n);
	ko.res(n);
	for(i=0;i<n;i++){cin>>p[i];}
	for(i=0;i<n;i++){
		int d;cin>>d;
		while(d--){
			int c;cin>>c;c--;
			ko[i].pub(c);
		}
	}
	int ret,syo,dai;
	tie(ret,syo,dai)=solve(0,-10001,10001);
	cout<<syo<<" "<<dai<<endl;
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3796
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;

using pii = pair<int, int>;
const int inf = 1e9;

template<typename T>
std::vector<T> table(int n, T v) { return std::vector<T>(n, v); }

template <class... Args>
auto table(int n, Args... args) {
    auto val = table(args...);
    return std::vector<decltype(val)>(n, std::move(val));
}

int main() {
    int n; cin >> n;
    vector<int> p(n), vs = {-inf, inf};
    for(auto& x : p) {
        cin >> x;
        vs.push_back(x);
        vs.push_back(-x);
    }
    sort(begin(vs), end(vs));
    vs.erase(unique(begin(vs), end(vs)), end(vs));
    auto get_idx = [&] (int val) -> int {
        return lower_bound(begin(vs), end(vs), val) - begin(vs);
    };
    vector<vector<int>> g(n);
    for(int i = 0; i < n; ++i) {
        int k; cin >> k;
        g[i].resize(k);
        for(auto& c : g[i]) {
            cin >> c;
            c--;
        }
    }

    auto max_dp = table(n, vs.size(), vs.size(), make_pair(-inf, 0));
    auto min_dp = table(n, vs.size(), vs.size(), make_pair(inf, 0));
    function<pii(int, int, int, bool)> dfs = [&] (int v, int alpha, int beta, bool is_min) {
        if(g[v].empty()) return make_pair(1, p[v]); // leaf

        auto& res = (is_min ? min_dp[v][alpha][beta] : max_dp[v][alpha][beta]);
        if(abs(res.first) != inf) return res;

        sort(begin(g[v]), end(g[v]));
        do {
            int talpha = alpha;
            pii cur = make_pair(0, -inf);
            for(auto const ch : g[v]) {
                auto val = dfs(ch, get_idx(-vs[beta]), get_idx(-vs[talpha]), is_min);
                val.second = -val.second;
                cur.first += val.first;
                if(val.second >= vs[beta]) {
                    cur.second = val.second;
                    break;
                }
                if(val.second > vs[talpha]) {
                    talpha = get_idx(val.second);
                }
            }
            if(cur.second == -inf) { // not occured val.second >= beta
                cur.second = vs[talpha];
            }
            if(is_min) res = min(res, cur);
            else       res = max(res, cur);
        } while(next_permutation(begin(g[v]), end(g[v])));

        return res;
    };

    cout << dfs(0, 0, vs.size() - 1, true).first << " " << dfs(0, 0, vs.size() - 1, false).first << endl;
}
accuracy: 1
time_ms: 220
memory_kb: 45600
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


template<typename T>
vector<T> compress(vector<T> v){
  sort(v.begin(),v.end());
  v.erase(unique(v.begin(),v.end()),v.end());
  return v;
}

template<typename T>
map<T, Int> dict(const vector<T> &v){
  map<T, Int> res;
  for(Int i=0;i<(Int)v.size();i++)
    res[v[i]]=i;
  return res;
}


template<typename T>
vector<T> make_v(size_t a){return vector<T>(a);}

template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts){
  return vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}

template<typename T,typename V>
typename enable_if<is_class<T>::value==0>::type
fill_v(T &t,const V &v){t=v;}

template<typename T,typename V>
typename enable_if<is_class<T>::value!=0>::type
fill_v(T &t,const V &v){
  for(auto &e:t) fill_v(e,v);
}

//INSERT ABOVE HERE
signed main(){
  Int n;
  cin>>n;
  vector<Int> x(n);
  for(Int i=0;i<n;i++) cin>>x[i];
  vector<vector<Int> > G(n);
  for(Int i=0;i<n;i++){
    Int k;
    cin>>k;
    while(k--){
      Int t;
      cin>>t;
      t--;
      G[i].emplace_back(t);
    }
  }
  vector<Int> vx;
  for(Int i=0;i<n;i++){
    vx.emplace_back(-x[i]);
    vx.emplace_back(+x[i]);
  }
  vx.emplace_back(-2e5);
  vx.emplace_back(+2e5);
  vx=compress(vx);
  auto mx=dict(vx);

  auto val=make_v<Int>(n,mx.size(),mx.size());
  auto dp1=make_v<Int>(n,mx.size(),mx.size());
  auto dp2=make_v<Int>(n,mx.size(),mx.size());
  fill_v(dp1,-1);
  fill_v(dp2,-1);
  function<Int(Int, Int, Int)> dfs=
    [&](Int v,Int a,Int b)->Int{
      Int &res=val[v][a][b];
      Int &t1=dp1[v][a][b],&t2=dp2[v][a][b];
      if(~t1) return res;
      if(G[v].empty()){
        t1=t2=1;
        return val[v][a][b]=x[v];
      }
      t1=n+1;t2=-1;
      sort(G[v].begin(),G[v].end());
      do{
        Int c=a,d=b,s1=0,s2=0,flg=0;
        for(Int u:G[v]){
          Int w=mx[-dfs(u,mx[-vx[d]],mx[-vx[c]])];
          s1+=dp1[u][mx[-vx[d]]][mx[-vx[c]]];
          s2+=dp2[u][mx[-vx[d]]][mx[-vx[c]]];
          if(w>=d){
            res=vx[w];
            flg=1;
            break;
          }else if(w>c){
            c=w;
          }
        }
        chmin(t1,s1);
        chmax(t2,s2);
        if(!flg) res=vx[c];       
      }while(next_permutation(G[v].begin(),G[v].end()));
      return res;
    };  
  dfs(0,0,mx.size()-1);
  cout<<dp1[0][0][mx.size()-1]<<" "<<dp2[0][0][mx.size()-1]<<endl;  
  return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 66860
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

using pi = pair<int,int>;
using P = pair<pi,int>;

const int N = 111;
const int INF = 191919;

int n;
int p[N];
vector<int> ch[N];

map<pi,P> dp[N];
P dfs(int v, int a, int b){
    if(dp[v].count({a,b})) return dp[v][{a,b}];

    if(ch[v].size() == 0){
        return {{1,1},p[v]};
    }

    int sz = ch[v].size();
    int res = -INF;
    int mn = N, mx = 0;

    do{
        int ta=a, tb=b;
        int tmn = 0, tmx = 0;
        rep(i,sz){
            P val = dfs(ch[v][i], -tb, -ta);
            int vv = -val.se;
            tmn += val.fi.fi;
            tmx += val.fi.se;
            if(vv >= tb){
                ta = vv;
                break;
            }
            if(vv > ta){
                ta = vv;
            }
        }

        res = max(res,ta);
        mn = min(mn, tmn);
        mx = max(mx, tmx);

    }while(next_permutation(all(ch[v])));

    // printf(" %d %d %d  ->   [%d,%d],  val = %d\n",v,a,b,mn,mx,res);

    P ret = {{mn,mx}, res};
    dp[v][{a,b}] = ret;
    return ret;
}

int main(){
    cin >>n;
    rep(i,n) cin >>p[i];
    rep(i,n){
        int k;
        cin >>k;
        while(k--){
            int t;
            cin >>t;
            --t;
            ch[i].pb(t);
        }
        sort(all(ch[i]));
    }

    pi ans = dfs(0,-INF,INF).fi;
    cout << ans.fi << " " << ans.se << endl;
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 3820
final_rank: 2

code_snippet: #include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int n;
P dp_min[105][205][205];
P dp_max[105][205][205];
bool used[105][205][205];
vector<int> val;
vector<int> G[105];
int p[205];

struct data{
	int a,b,cnt,st;
	data(){}
	data(int aa,int bb,int cc,int ss){
		a=aa;
		b=bb;
		cnt=cc;
		st=ss;
	}
};

void solve(int v,int l,int r){
	if(used[v][l][r])return;
	//printf("%d %d %d\n",v,l,r);
	used[v][l][r]=true;
	if(G[v].size()==0){
		int pos=lower_bound(val.begin(),val.end(),p[v])-val.begin();
		dp_min[v][l][r]=P(1,pos);
		dp_max[v][l][r]=P(1,pos);
		//printf("%d %d\n",v,val[pos]);
		return;
	}
	int ord[5];
	for(int i=0;i<G[v].size();i++){
		ord[i]=i;
	}
	dp_min[v][l][r]=P(114514,114514);
	do{
		queue<data> que;
		que.push(data(l,r,0,0));
		while(que.size()){
			data d=que.front();
			que.pop();
			if(d.st==G[v].size()){
				dp_min[v][l][r]=min(dp_min[v][l][r],P(d.cnt,d.a));
				dp_max[v][l][r]=max(dp_max[v][l][r],P(d.cnt,d.a));
				continue;
			}
			int nv=G[v][ord[d.st]];
			int ra=lower_bound(val.begin(),val.end(),-val[d.a])-val.begin();
			int rb=lower_bound(val.begin(),val.end(),-val[d.b])-val.begin();
			solve(nv,rb,ra);
			int rpos=lower_bound(val.begin(),val.end(),-val[dp_min[nv][rb][ra].second])-val.begin();
			if(rpos>=d.b){
				dp_min[v][l][r]=min(dp_min[v][l][r],P(d.cnt+dp_min[nv][rb][ra].first,rpos));
				dp_max[v][l][r]=max(dp_max[v][l][r],P(d.cnt+dp_min[nv][rb][ra].first,rpos));	
			}else{
				que.push(data(max(d.a,rpos),d.b,d.cnt+dp_min[nv][rb][ra].first,d.st+1));
			}
			rpos=lower_bound(val.begin(),val.end(),-val[dp_max[nv][rb][ra].second])-val.begin();
			if(rpos>=d.b){
				dp_min[v][l][r]=min(dp_min[v][l][r],P(d.cnt+dp_max[nv][rb][ra].first,rpos));
				dp_max[v][l][r]=max(dp_max[v][l][r],P(d.cnt+dp_max[nv][rb][ra].first,rpos));	
			}else{
				que.push(data(max(d.a,rpos),d.b,d.cnt+dp_max[nv][rb][ra].first,d.st+1));
			}
		}
	}while(next_permutation(ord,ord+G[v].size()));
	//printf("%d %d %d (%d,%d) (%d,%d)\n",v,l,r,dp_min[v][l][r].first,val[dp_min[v][l][r].second],dp_max[v][l][r].first,val[dp_max[v][l][r].second]);
}

int main(void){
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&p[i]);
		val.push_back(p[i]);
		val.push_back(-p[i]);
	}
	val.push_back(114514);
	val.push_back(-114514);
	sort(val.begin(),val.end());
	val.erase(unique(val.begin(),val.end()),val.end());
	for(int i=0;i<n;i++){
		int k;
		scanf("%d",&k);
		for(int j=0;j<k;j++){
			int a;
			scanf("%d",&a);
			a--;
			G[i].push_back(a);
		}
	}
	solve(0,0,val.size()-1);
	printf("%d %d\n",dp_min[0][0][val.size()-1].first,dp_max[0][0][val.size()-1].first);
	return 0;
}
accuracy: 1
time_ms: 1250
memory_kb: 73628
final_rank: 20

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 105

enum Type{
	MIN,
	MAX,
};

int V;
int table[6][120][5];
int num_pattern[6],calc_array[6];
int value[NUM],num_child[NUM],child[NUM][5];
int map_index;
int dp[2][NUM][2*NUM][2*NUM];
map<int,int> MAP;
bool check[6],visited[NUM][2*NUM][2*NUM];


void makeTable(int max_num,int index){

	if(index == max_num){

		for(int i = 0; i < max_num; i++){
			table[max_num][num_pattern[max_num]][i] = calc_array[i]-1;
		}
		num_pattern[max_num]++;

		return;
	}

	for(int next_num = 1; next_num <= max_num; next_num++){

		if(check[next_num])continue;
		check[next_num] = true;
		calc_array[index] = next_num;
		makeTable(max_num,index+1);
		check[next_num] = false;
	}
}

void registMAP(int num){

	auto at = MAP.find(num);

	if(at == MAP.end()){
		MAP[num] = map_index++;
	}

	at = MAP.find(-num);

	if(at == MAP.end()){
		MAP[-num] = map_index++;
	}
}

void dfs(int node_id){

	if(num_child[node_id] == 0){

		return;
	}

	for(int i = 0; i < num_child[node_id]; i++){
		dfs(child[node_id][i]);
	}
	value[node_id] = -BIG_NUM;

	for(int i = 0; i < num_child[node_id]; i++){
		value[node_id] = max(value[node_id],-value[child[node_id][i]]);
	}
}

void recursive(int node_id,int A,int B){

	if(visited[node_id][MAP[A]][MAP[B]])return;

	visited[node_id][MAP[A]][MAP[B]] = true;

	if(num_child[node_id] == 0){
		dp[MIN][node_id][MAP[A]][MAP[B]] = 1;
		dp[MAX][node_id][MAP[A]][MAP[B]] = 1;
		return;
	}

	int tmp_A,tmp_B,tmp_child;
	int minimum = BIG_NUM,maximum = -BIG_NUM;
	int tmp_min,tmp_max,val;

	for(int i = 0; i < num_pattern[num_child[node_id]]; i++){

		tmp_min = 0;
		tmp_max = 0;
		tmp_A = A;
		tmp_B = B;

		for(int k = 0; k < num_child[node_id]; k++){

			tmp_child = child[node_id][table[num_child[node_id]][i][k]];
			recursive(tmp_child,-tmp_B,-tmp_A);

			val = -value[tmp_child];

			tmp_min += dp[MIN][tmp_child][MAP[-tmp_B]][MAP[-tmp_A]];
			tmp_max += dp[MAX][tmp_child][MAP[-tmp_B]][MAP[-tmp_A]];

			if(val >= tmp_B){
				break;
			}
			if(val > tmp_A){
				tmp_A = val;
			}
		}
		minimum = min(minimum,tmp_min);
		maximum = max(maximum,tmp_max);
	}
	dp[MIN][node_id][MAP[A]][MAP[B]] = minimum;
	dp[MAX][node_id][MAP[A]][MAP[B]] = maximum;

}

int main(){

	for(int i = 1; i <= 5; i++){
		num_pattern[i] = 0;
	}

	for(int max_num = 1; max_num <= 5; max_num++){

		for(int i = 1; i <= max_num; i++){
			check[i] = false;
		}
		for(int first_num = 1; first_num <= max_num; first_num++){
			check[first_num] = true;
			calc_array[0] = first_num;
			makeTable(max_num,1);
			check[first_num] = false;
		}
	}

	scanf("%d",&V);

	registMAP(BIG_NUM);

	for(int i = 0; i < V; i++){
		scanf("%d",&value[i]);
		registMAP(value[i]);
	}

	int tmp;
	for(int i = 0; i < V; i++){

		scanf("%d",&num_child[i]);

		for(int k = 0; k < num_child[i]; k++){
			scanf("%d",&tmp);
			tmp--;
			child[i][k] = tmp;
		}
	}

	for(int i = 0; i < V; i++){
		for(int k = 0; k < map_index; k++){
			for(int p = 0; p < map_index; p++){

				visited[i][k][p] = false;

				dp[MIN][i][k][p] = BIG_NUM;
				dp[MAX][i][k][p] = -BIG_NUM;
			}
		}
	}

	dfs(0);
	recursive(0,-BIG_NUM,BIG_NUM);

	printf("%d %d\n",dp[MIN][0][MAP[-BIG_NUM]][MAP[BIG_NUM]],dp[MAX][0][MAP[-BIG_NUM]][MAP[BIG_NUM]]);

	return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 34492
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;

const Int inf = 1LL<<55;

Int n;
Int p[111];
vector<Int> graph[111];

map<Int, Int> mp;

using Pi = pair<Int, Int>;

Pi val[111][222][222];
Int dp_min[111][222][222];
Int dp_max[111][222][222];
bool visited[111][222][222];

Pi dfs(Int v, Int a, Int b) {
  if(visited[v][mp[a]][mp[b]]) return val[v][mp[a]][mp[b]];
  visited[v][mp[a]][mp[b]] = true;  
  if(graph[v].empty()) {
    dp_min[v][mp[a]][mp[b]] = 1;
    dp_max[v][mp[a]][mp[b]] = 1;
    val[v][mp[a]][mp[b]] = Pi(p[v], p[v]);
    //cout<<v<<" "<<val[v][mp[a]][mp[b]].first<<" "<<val[v][mp[a]][mp[b]].second<<endl;
    return val[v][mp[a]][mp[b]];
  }
  val[v][mp[a]][mp[b]] = Pi(-inf, inf);
  dp_min[v][mp[a]][mp[b]] = inf;
  dp_max[v][mp[a]][mp[b]] = -inf;  
  do {
    Pi a_tmp = Pi(a, a), b_tmp = Pi(b, b);
    Int mn = 0, mx = 0;
    bool f_mn = true, f_mx = true;
    for(Int u : graph[v]) {
      if(f_mn) {
	Int x = -dfs(u, -b_tmp.first, -a_tmp.first).first;
	mn += dp_min[u][mp[-b_tmp.first]][mp[-a_tmp.first]];
	if(x >= b_tmp.first) {
	  a_tmp.first = x;
	  f_mn = false;
	} else if(x > a_tmp.first) {
	  a_tmp.first = x;
	}
      }
      if(f_mx) {
	Int x = -dfs(u, -b_tmp.second, -a_tmp.second).second;
	mx += dp_max[u][mp[-b_tmp.second]][mp[-a_tmp.second]];	
	if(x >= b_tmp.second) {
	  a_tmp.second = x;
	  f_mx = false;
	} else if(x > a_tmp.second) {
	  a_tmp.second = x;
	}
      }
    }
    if(dp_min[v][mp[a]][mp[b]] >= mn) {
      dp_min[v][mp[a]][mp[b]] = mn;
      val[v][mp[a]][mp[b]].first = max(val[v][mp[a]][mp[b]].first, a_tmp.first);
    }
    if(dp_max[v][mp[a]][mp[b]] <= mx) {
      dp_max[v][mp[a]][mp[b]] = mx;
      val[v][mp[a]][mp[b]].second = min(val[v][mp[a]][mp[b]].second, a_tmp.second);
    }
  }while(next_permutation(graph[v].begin(), graph[v].end()));
  //cout<<v<<" "<<val[v][mp[a]][mp[b]].first << " " << val[v][mp[a]][mp[b]].second << endl;
  //assert(val[v][mp[a]][mp[b]].first == val[v][mp[a]][mp[b]].second); 
  return val[v][mp[a]][mp[b]];
}

signed main(){  
  cin.tie(0);
  ios::sync_with_stdio(0);

  cin >> n;
  for(Int i = 0; i < n; ++i) cin >> p[i];
  for(Int i = 0; i < n; ++i) {
    Int k; cin >> k;
    for(Int j = 0; j < k; ++j) {
      Int t; cin >> t; --t;
      graph[i].push_back(t);
    }
    sort(graph[i].begin(), graph[i].end());
  }
  vector<Int> vec;
  vec.push_back(-inf);
  vec.push_back(inf);
  for(Int i = 0; i < n; ++i) {
    vec.push_back(p[i]);
    vec.push_back(-p[i]);
  }
  sort(vec.begin(), vec.end());
  vec.erase(unique(vec.begin(), vec.end()), vec.end());
  for(Int i = 0; i < n; ++i) {
    mp[p[i]] = lower_bound(vec.begin(), vec.end(), p[i])-vec.begin();
    mp[-p[i]] = lower_bound(vec.begin(), vec.end(), -p[i])-vec.begin();
  }
  memset(visited, false, sizeof(visited));
  dfs(0, -inf, inf);
  cout << dp_min[0][mp[-inf]][mp[inf]] << " " << dp_max[0][mp[-inf]][mp[inf]] << endl;
  
  return 0;
}
accuracy: 1
time_ms: 410
memory_kb: 28224
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;

const Int inf = 1LL<<55;

Int n;
Int p[111];
vector<Int> graph[111];

unordered_map<Int, Int> mp;

using Pi = pair<Int, Int>;

Pi val[111][222][222];
Int dp_min[111][222][222];
Int dp_max[111][222][222];
bool visited[111][222][222];

Pi dfs(Int v, Int a, Int b) {
  if(visited[v][mp[a]][mp[b]]) return val[v][mp[a]][mp[b]];
  visited[v][mp[a]][mp[b]] = true;  
  if(graph[v].empty()) {
    dp_min[v][mp[a]][mp[b]] = 1;
    dp_max[v][mp[a]][mp[b]] = 1;
    val[v][mp[a]][mp[b]] = Pi(p[v], p[v]);
    //cout<<v<<" "<<val[v][mp[a]][mp[b]].first<<" "<<val[v][mp[a]][mp[b]].second<<endl;
    return val[v][mp[a]][mp[b]];
  }
  val[v][mp[a]][mp[b]] = Pi(-inf, inf);
  dp_min[v][mp[a]][mp[b]] = inf;
  dp_max[v][mp[a]][mp[b]] = -inf;  
  do {
    Pi a_tmp = Pi(a, a), b_tmp = Pi(b, b);
    Int mn = 0, mx = 0;
    bool f_mn = true, f_mx = true;
    for(Int u : graph[v]) {
      if(f_mn) {
	Int x = -dfs(u, -b_tmp.first, -a_tmp.first).first;
	mn += dp_min[u][mp[-b_tmp.first]][mp[-a_tmp.first]];
	if(x >= b_tmp.first) {
	  a_tmp.first = x;
	  f_mn = false;
	} else if(x > a_tmp.first) {
	  a_tmp.first = x;
	}
      }
      if(f_mx) {
	Int x = -dfs(u, -b_tmp.second, -a_tmp.second).second;
	mx += dp_max[u][mp[-b_tmp.second]][mp[-a_tmp.second]];	
	if(x >= b_tmp.second) {
	  a_tmp.second = x;
	  f_mx = false;
	} else if(x > a_tmp.second) {
	  a_tmp.second = x;
	}
      }
    }
    if(dp_min[v][mp[a]][mp[b]] >= mn) {
      dp_min[v][mp[a]][mp[b]] = mn;
      val[v][mp[a]][mp[b]].first = max(val[v][mp[a]][mp[b]].first, a_tmp.first);
    }
    if(dp_max[v][mp[a]][mp[b]] <= mx) {
      dp_max[v][mp[a]][mp[b]] = mx;
      val[v][mp[a]][mp[b]].second = min(val[v][mp[a]][mp[b]].second, a_tmp.second);
    }
  }while(next_permutation(graph[v].begin(), graph[v].end()));
  //cout<<v<<" "<<val[v][mp[a]][mp[b]].first << " " << val[v][mp[a]][mp[b]].second << endl;
  return val[v][mp[a]][mp[b]];
}

signed main(){  
  cin.tie(0);
  ios::sync_with_stdio(0);

  cin >> n;
  for(Int i = 0; i < n; ++i) cin >> p[i];
  for(Int i = 0; i < n; ++i) {
    Int k; cin >> k;
    for(Int j = 0; j < k; ++j) {
      Int t; cin >> t; --t;
      graph[i].push_back(t);
    }
    sort(graph[i].begin(), graph[i].end());
  }
  vector<Int> vec;
  vec.push_back(-inf);
  vec.push_back(inf);
  for(Int i = 0; i < n; ++i) {
    vec.push_back(p[i]);
    vec.push_back(-p[i]);
  }
  sort(vec.begin(), vec.end());
  vec.erase(unique(vec.begin(), vec.end()), vec.end());
  for(Int i = 0; i < n; ++i) {
    mp[p[i]] = lower_bound(vec.begin(), vec.end(), p[i])-vec.begin();
    mp[-p[i]] = lower_bound(vec.begin(), vec.end(), -p[i])-vec.begin();
  }
  memset(visited, false, sizeof(visited));
  dfs(0, -inf, inf);
  cout << dp_min[0][mp[-inf]][mp[inf]] << " " << dp_max[0][mp[-inf]][mp[inf]] << endl;
  
  return 0;
}
accuracy: 1
time_ms: 880
memory_kb: 28192
final_rank: 17

code_snippet: #include <bits/stdc++.h>
 
#define _overload(_1,_2,_3,name,...) name
#define _rep(i,n) _range(i,0,n)
#define _range(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define rep(...) _overload(__VA_ARGS__,_range,_rep,)(__VA_ARGS__)
 
#define _rrep(i,n) _rrange(i,n,0)
#define _rrange(i,a,b) for(int i=(int)(a)-1;i>=(int)(b);--i)
#define rrep(...) _overload(__VA_ARGS__,_rrange,_rrep,)(__VA_ARGS__)
 
#define _all(arg) begin(arg),end(arg)
#define uniq(arg) sort(_all(arg)),(arg).erase(unique(_all(arg)),end(arg))
#define getidx(ary,key) lower_bound(_all(ary),key)-begin(ary)
#define clr(a,b) memset((a),(b),sizeof(a))
#define bit(n) (1LL<<(n))
 
// #define DEBUG
 
#ifdef DEBUG
    #define dump(...) fprintf(stderr, __VA_ARGS__)
#else
    #define dump(...)
#endif
 
template<class T>bool chmax(T &a, const T &b) { return (a<b)?(a=b,1):0;}
template<class T>bool chmin(T &a, const T &b) { return (b<a)?(a=b,1):0;}
 
using namespace std;
using ll=long long;
using vi=vector<int>;
using vll=vector<ll>;
 
const double EPS = 1e-10;
const double PI = acos(-1.0);
const int inf =1 << 30;
const ll mod=1000000007LL;
const int dx[4]={1,0,-1,0};
const int dy[4]={0,1,0,-1};
 
 
ll extgcd(ll a,ll b,ll& x,ll& y){x=1,y=0;ll g=a;if(b!=0) g=extgcd(b,a%b,y,x),y-=a/b*x;return g;}
ll ADD(const ll &a, const ll &b,const ll &mod) { return (a+b)%mod;}
ll SUB(const ll &a, const ll &b,const ll &mod) { return (a-b+mod)%mod;}
ll MUL(const ll &a, const ll &b,const ll &mod) { return (1LL*a*b)%mod;}
ll DIV(const ll &a, const ll &b,const ll &mod) {ll x,y; extgcd(b,mod,x,y);return MUL(a,(x+mod)%mod,mod);}
 
random_device rd;
mt19937 mt(rd());
uniform_int_distribution<int> dice(1,6);
uniform_real_distribution<double> score(0.0,10.0);

int n, m;
vi eval;
vector<vi> G;
vector<vector<vi>> min_num, max_num, memo;
vi scores;
map<int, int> s2i;

int negamax(int v, int alpha, int beta){
    int& mi  = min_num[v][s2i[alpha]][s2i[beta]];
    int& ma  = max_num[v][s2i[alpha]][s2i[beta]];
    int& ret = memo   [v][s2i[alpha]][s2i[beta]];
    if(ma != -1){
        return ret;
    }

    int nc = G[v].size();

    // leaf
    if(nc == 0){
        mi = 1;
        ma = 1;
        return ret = eval[v];
    }

    // internal
    vi perm(nc); rep(i, nc) perm[i] = i;
    do {
        int alpha_org = alpha;
        int beta_org  = beta;
        
        int curmi = 0, curma = 0;
        rep(i, nc){
            int nv = G[v][perm[i]];
            int val = -negamax(nv, -beta, -alpha);
            curmi += min_num[nv][s2i[-beta]][s2i[-alpha]];
            curma += max_num[nv][s2i[-beta]][s2i[-alpha]];

            if(val >= beta){
                ret = val;
                break;
            }
            chmax(alpha, val);
            ret = alpha;
        }
        chmin(mi, curmi);
        chmax(ma, curma);

        alpha = alpha_org;
        beta  = beta_org;
    } while(next_permutation(_all(perm)));

    return ret;
}

int main(void){
    cin.tie(0);
    ios::sync_with_stdio(false);

    cin >> n;
    eval = vi(n); for(auto& e : eval) cin >> e;
    G = vector<vi>(n);
    scores = {-inf, inf};
    rep(v, n){
        int k; cin >> k;
        rep(loop, k){
            int u; cin >> u; u--;
            G[v].emplace_back(u);
        }
        if(k == 0){
            scores.emplace_back(eval[v]);
            scores.emplace_back(-eval[v]);
        }
    }
    sort(_all(scores));
    scores.erase(unique(_all(scores)), end(scores));
    m = scores.size();
    rep(i, m) s2i[scores[i]] = i;

    min_num = vector<vector<vi>>(n, vector<vi>(m, vi(m, inf)));
    max_num = vector<vector<vi>>(n, vector<vi>(m, vi(m, -1)));
    memo    = vector<vector<vi>>(n, vector<vi>(m, vi(m, -inf)));

    negamax(0, -inf, inf);
    cout << min_num[0][0][m-1] << " " << max_num[0][0][m-1] << endl;

    return 0;
}
accuracy: 1
time_ms: 290
memory_kb: 35468
final_rank: 11

code_snippet: #include <map>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int n, p[109], dp1[109][209][209], dp2[109][209][209], ptr[20009]; bool vis[109][209][209]; vector<int> q, G[109];
void calc_evaluation(int pos) {
	if (G[pos].size() == 0) return;
	p[pos] = -999999999;
	for (int i : G[pos]) {
		calc_evaluation(i);
		p[pos] = max(p[pos], -p[i]);
	}
}
void solve(int pos, int alpha, int beta) {
	if (G[pos].size() == 0) {
		dp1[pos][ptr[alpha + 10001]][ptr[beta + 10001]] = 1;
		dp2[pos][ptr[alpha + 10001]][ptr[beta + 10001]] = 1;
		return;
	}
	if (vis[pos][ptr[alpha + 10001]][ptr[beta + 10001]]) return;
	vector<int> perm(G[pos].size());
	for (int i = 0; i < perm.size(); i++) perm[i] = i;
	int ret1 = n, ret2 = 0;
	do {
		int alpha2 = alpha, beta2 = beta, cnt_min = 0, cnt_max = 0;
		for (int i = 0; i < perm.size(); i++) {
			int chl = G[pos][perm[i]];
			int val = -p[chl];
			solve(chl, -beta2, -alpha2);
			cnt_min += dp1[chl][ptr[-beta2 + 10001]][ptr[-alpha2 + 10001]];
			cnt_max += dp2[chl][ptr[-beta2 + 10001]][ptr[-alpha2 + 10001]];
			if (val >= beta2) break;
			alpha2 = max(val, alpha2);
		}
		ret1 = min(ret1, cnt_min);
		ret2 = max(ret2, cnt_max);
	} while (next_permutation(perm.begin(), perm.end()));
	vis[pos][ptr[alpha + 10001]][ptr[beta + 10001]] = true;
	dp1[pos][ptr[alpha + 10001]][ptr[beta + 10001]] = ret1;
	dp2[pos][ptr[alpha + 10001]][ptr[beta + 10001]] = ret2;
}
int main() {
	cin >> n;
	for (int i = 0; i < n; i++) cin >> p[i];
	q.resize(2 * n);
	for (int i = 0; i < n; i++) q[i] = p[i], q[n + i] = -p[i];
	q.push_back(-10001);
	q.push_back(10001);
	sort(q.begin(), q.end());
	q.erase(unique(q.begin(), q.end()), q.end());
	for (int i = 0; i < q.size(); i++) ptr[q[i] + 10001] = i;
	for (int i = 0; i < n; i++) {
		int c, x; cin >> c;
		for (int j = 0; j < c; j++) {
			cin >> x; x--;
			G[i].push_back(x);
		}
	}
	calc_evaluation(0);
	solve(0, -10001, 10001);
	cout << dp1[0][0][q.size() - 1] << ' ' << dp2[0][0][q.size() - 1] << endl;
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 10676
final_rank: 4

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class T>
using Table = vector<vector<T>>;
const ld eps=1e-9;

//// < "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\a.txt" > "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\b.answer"

struct Node {
	int value;
	vector<int>edges;
	Node() :value(0), edges() {

	}
};
struct aa {
	int value;
	int amin;
	int amax;
};
map<int, int>mp;

aa memo[100][202][202];
aa getans(const int now,const vector<Node>&ns,const int alp,const int bet) {
	if (memo[now][mp[alp]][mp[bet]].amax != -1)return memo[now][mp[alp]][mp[bet]];
	else {
		Node no(ns[now]);
		if (no.edges.empty())return memo[now][mp[alp]][mp[bet]]=aa{ ns[now].value,1,1 };
		else {
			int realvalue = -1e9;
			{
				int nalp = alp;
				int nbet = bet;
				for (int i = 0; i < no.edges.size(); ++i) {
					aa ans = getans(no.edges[i], ns, -nbet, -nalp);
					realvalue = max(realvalue, -ans.value);
				}
			}
			aa ret{ realvalue,int(1e9),int(-1e9) };
			vector<int>perms(no.edges.size());
			iota(perms.begin(), perms.end(), 0);
			do {
				int amintime = 0;
				int nalp = alp;
				int nbet = bet;
				int amaxtime = 0;
				for (int i = 0; i < no.edges.size(); ++i) {
					aa ans = getans(no.edges[perms[i]], ns, -nbet, -nalp);
					amintime += ans.amin;
					amaxtime += ans.amax;
					if (-ans.value >= nbet) {
						break;
					}
					else if (-ans.value > nalp) {
						nalp = -ans.value;
					}
				}
				ret.amin = min(ret.amin, amintime);
				ret.amax = max(ret.amax, amaxtime);
			} while (next_permutation(perms.begin(), perms.end()));
			return memo[now][mp[alp]][mp[bet]]=ret;
		}
	}
}

int main() {
	int N; cin >> N;
	for (int i = 0; i < 100; ++i) {
		for (int j = 0; j < 202; ++j) {
			for (int k = 0; k < 202; ++k) {
				memo[i][j][k] = aa{ -1,-1,-1 };
			}
		}
	}
	vector<Node>nodes(N);
	vector<int>nums;
	for (int i = 0; i < N; ++i) {
		int a; cin >> a;
		nodes[i].value = a;
		nums.emplace_back(a);
		nums.emplace_back(-a);
	}
	nums.emplace_back(int(1e9));
	nums.emplace_back(int(-1e9));
	sort(nums.begin(), nums.end());
	nums.erase(unique(nums.begin(), nums.end()), nums.end());
	for (int i = 0; i < nums.size(); ++i) {
		mp[nums[i]] = i;
	}
	for (int i = 0; i < N; ++i) {
		int k; cin >> k;
		for (int j = 0; j < k; ++j) {
			int a; cin >> a; a--;
			nodes[i].edges.push_back(a);
		}
	}
	aa ans=getans(0, nodes, int(-1e9), int(1e9));
	cout << ans.amin <<" "<< ans.amax<< endl; 
	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 50964
final_rank: 9

code_snippet: #include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
vector<int>g[210];
int p[210];
int z[210];
int v[110][210][210];
int val[110][210][210];
int sz=0;
int dp[2][110][210][210];
int con[31000];
int A=15000;
int calc(int at,int l,int r,int dep){
	if(v[at][l][r])return val[at][l][r];
	if(g[at].size()==0){
		dp[0][at][l][r]=dp[1][at][l][r]=1;
		return val[at][l][r]=p[at]*dep;
	}
	int perm[10];
	for(int i=0;i<g[at].size();i++){
		perm[i]=i;
	}
	int len=g[at].size();
	int best=z[0];
	for(int i=0;i<len;i++){
		best=max(best,-calc(g[at][i],0,sz-1,dep));
	}
	val[at][l][r]=best;
	int r1=9999999;
	int r2=0;
	do{
		int t1=0;
		int t2=0;
		int va=z[l];
		int vb=z[r];
		for(int i=0;i<len;i++){
			int tmp=-calc(g[at][perm[i]],con[A-vb],con[A-va],dep);
			t1+=dp[0][g[at][perm[i]]][con[A-vb]][con[A-va]];
			t2+=dp[1][g[at][perm[i]]][con[A-vb]][con[A-va]];
			if(tmp>va){
				va=tmp;
			}
			if(va>=vb)break;
		}
		r1=min(r1,t1);
		r2=max(r2,t2);
	}while(next_permutation(perm,perm+len));
	dp[0][at][l][r]=r1;
	dp[1][at][l][r]=r2;
	v[at][l][r]=1;
	return val[at][l][r];
}
int main(){
	int a;scanf("%d",&a);
	for(int i=0;i<a;i++)scanf("%d",p+i);
	for(int i=0;i<a;i++){
		int b;scanf("%d",&b);
		for(int j=0;j<b;j++){
			int c;scanf("%d",&c);c--;
			g[i].push_back(c);
		}
	}
	for(int i=0;i<a;i++){
		z[sz++]=p[i];
		z[sz++]=-p[i];
	}
	z[sz++]=11111;
	z[sz++]=-11111;
	std::sort(z,z+sz);
	for(int i=0;i<sz;i++){
		con[z[i]+A]=i;
	}
	for(int i=0;i<a;i++)for(int j=0;j<sz;j++)for(int k=0;k<sz;k++){
		dp[0][i][j][k]=dp[1][i][j][k]=-1;
	}
	calc(0,0,sz-1,1);
	//for(int i=0;i<a;i++)printf("%d\n",val[i][0][sz-1]);
	printf("%d %d\n",dp[0][0][0][sz-1],dp[1][0][0][sz-1]);
}
accuracy: 1
time_ms: 50
memory_kb: 76700
final_rank: 12