from collections import defaultdict from atcoder.scc import SCCGraph def bsearch(low: int, high: int, pred) -> int: assert pred(low) lo = low hi = high res = low while lo <= hi: m = (lo + hi) // 2 if pred(m): res = max(res, m) lo = m + 1 else: hi = m - 1 return res def scc(n: int, adj: dict[int, list[int]]) -> list[list[int]]: """グラフを強連結成分分解する。 Args: n: 頂点数 adj: 隣接リスト {u: [v...]} Returns: 強連結成分のリスト (トポロジカル順) """ g = SCCGraph(n) for u, vs in adj.items(): for v in vs: g.add_edge(u, v) return g.scc() INF = 1 << 62 N = int(input()) A = list(map(int, input().split())) B = list(map(int, input().split())) C = list(map(lambda x: int(x)-1, input().split())) r_adj = defaultdict(list) # 逆辺 for i, c in enumerate(C): r_adj[i].append(c) # m 本作れるか def can(m: int) -> bool: # xs = [a - b * m for a, b in zip(A, B)] # 本数の余り(不足) xs = A.copy() for i, b in enumerate(B): xs[i] -= b * m # Functional Graph で本数の不足を伝搬していく for g in cc: x = sum(xs[v] for v in g) # 不足を次の SCC へ伝搬 if x < 0: gset = set(g) moved = False for v in g: if moved: break for to in r_adj[v]: if to in gset: continue xs[to] += x # 伝搬 moved = True break if not moved: # 不足を補えない return False return True cc = scc(N, r_adj) ans = bsearch(0, INF, can) print(ans)