Bandits appeared in the city! One of them is trying to catch as many citizens as he can.

The city consists of $n$ squares connected by $n-1$ roads in such a way that it is possible to reach any square from any other square. The square number $1$ is the main square.

After Sunday walk all the roads were changed to one-way roads in such a way that it is possible to reach any square from the main square.

At the moment when the bandit appeared on the main square there were $a_i$ citizens on the $i$-th square. Now the following process will begin. First, each citizen that is currently on a square with some outgoing one-way roads chooses one of such roads and moves along it to another square. Then the bandit chooses one of the one-way roads outgoing from the square he is located and moves along it. The process is repeated until the bandit is located on a square with no outgoing roads. The bandit catches all the citizens on that square.

The bandit wants to catch as many citizens as possible; the citizens want to minimize the number of caught people. The bandit and the citizens know positions of all citizens at any time, the citizens can cooperate. If both sides act optimally, how many citizens will be caught?


-----Input-----

The first line contains a single integer $n$ — the number of squares in the city ($2 \le n \le 2\cdot10^5$).

The second line contains $n-1$ integers $p_2, p_3 \dots p_n$ meaning that there is a one-way road from the square $p_i$ to the square $i$ ($1 \le p_i < i$). 

The third line contains $n$ integers $a_1, a_2, \dots, a_n$ — the number of citizens on each square initially ($0 \le a_i \le 10^9$).


-----Output-----

Print a single integer — the number of citizens the bandit will catch if both sides act optimally.


-----Examples-----
Input
3
1 1
3 1 2

Output
3

Input
3
1 1
3 1 3

Output
4



-----Note-----

In the first example the citizens on the square $1$ can split into two groups $2 + 1$, so that the second and on the third squares will have $3$ citizens each.

In the second example no matter how citizens act the bandit can catch at least $4$ citizens.

Difficulty: HARD

Solutions:
import io
import os
from collections import Counter, defaultdict, deque
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc

def solve(N, P, A):
	graph = [[] for i in range(N + 1)]
	for (i, p) in enumerate(P, start=2):
		graph[p].append(i)
		graph[i].append(p)
	dp = [0 for i in range(N + 1)]
	subtreeSum = [0 for i in range(N + 1)]
	subtreeCount = [0 for i in range(N + 1)]

	@bootstrap
	def dfs(u, p):
		best = 0
		total = 0
		count = 0
		isLeaf = 1
		for v in graph[u]:
			if v != p:
				yield dfs(v, u)
				best = max(best, dp[v])
				total += subtreeSum[v]
				count += subtreeCount[v]
				isLeaf = 0
		if isLeaf:
			dp[u] = A[u - 1]
		else:
			spareCapacity = count * best - total
			assert spareCapacity >= 0
			needed = max(0, A[u - 1] - spareCapacity)
			inc = (needed + count - 1) // count
			dp[u] = best + inc
		subtreeSum[u] = A[u - 1] + total
		subtreeCount[u] = isLeaf + count
		yield
	dfs(1, -1)
	return dp[1]
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(N,) = [int(x) for x in input().split()]
P = [int(x) for x in input().split()]
A = [int(x) for x in input().split()]
ans = solve(N, P, A)
print(ans)


from collections import defaultdict
from math import ceil

def solve():
	n = int(input())
	graph = defaultdict(list)
	largest_leaf = defaultdict(int)
	leaf_count = defaultdict(int)
	subtree_sum = defaultdict(int)
	ans = 0
	for (i, p) in enumerate(input().split(), 2):
		graph[int(p)] += [i]
	a = {i: int(x) for (i, x) in enumerate(input().split(), 1)}
	for v in reversed(range(1, n + 1)):
		subtree_sum[v] = a[v]
		if len(graph[v]) == 0:
			largest_leaf[v] = subtree_sum[v]
			leaf_count[v] = 1
		else:
			largest_child_leaf = 0
			for child in graph[v]:
				largest_child_leaf = max(largest_child_leaf, largest_leaf[child])
				subtree_sum[v] += subtree_sum[child]
				leaf_count[v] += leaf_count[child]
			result_sum = max(largest_child_leaf * leaf_count[v], subtree_sum[v])
			largest_leaf[v] = ceil(result_sum / leaf_count[v])
		ans = max(ans, largest_leaf[v])
	print(ans)
solve()


n = int(input())
parent = [0] + [x - 1 for x in list(map(int, input().split()))]
citizen = list(map(int, input().split()))
sz = [1] * n
for i in range(1, n):
	sz[parent[i]] = 0
for i in range(n - 1, 0, -1):
	citizen[parent[i]] += citizen[i]
	sz[parent[i]] += sz[i]
ans = 0
for i in range(n):
	ans = max(ans, (citizen[i] + sz[i] - 1) // sz[i])
print(ans)


n = int(input())
p = list(map(int, input().split()))
a = list(map(int, input().split()))
tree = {}
for (i, pp) in enumerate(p, start=2):
	tree.setdefault(pp, []).append(i)
cache = {}
for s in range(n, 0, -1):
	children = tree.get(s, [])
	if len(children) == 0:
		cache[s] = (a[s - 1], a[s - 1], 1)
		continue
	ch_p = [cache[c] for c in children]
	ch_max = max((pp[0] for pp in ch_p))
	ch_sum = sum((pp[1] for pp in ch_p))
	ch_l = sum((pp[2] for pp in ch_p))
	sm = ch_sum + a[s - 1]
	m = sm // ch_l
	if sm % ch_l != 0:
		m += 1
	cache[s] = (max(ch_max, m), sm, ch_l)
print(cache[1][0])


import sys
input = sys.stdin.readline
from collections import defaultdict
n = int(input())
p = [int(i) for i in input().split() if i != '\n']
a = [int(i) for i in input().split() if i != '\n']
graph = defaultdict(list)
for i in range(n - 1):
	graph[p[i]].append(i + 2)
OBSERVE = 0
CHECK = 1
stack = [(OBSERVE, 1, 0)]
info = [0] * (n + 1)
while stack:
	(state, vertex, parent) = stack.pop()
	if state == OBSERVE:
		stack.append((CHECK, vertex, parent))
		for child in graph[vertex]:
			stack.append((OBSERVE, child, vertex))
	elif len(graph[vertex]) == 0:
		maxa = a[vertex - 1]
		suma = a[vertex - 1]
		count = 1
		info[vertex] = (maxa, suma, count)
	else:
		(maxa, suma, count) = (0, 0, 0)
		for child in graph[vertex]:
			maxa = max(info[child][0], maxa)
			suma += info[child][1]
			count += info[child][2]
		suma += a[vertex - 1]
		maxa = max(maxa, (suma + count - 1) // count)
		info[vertex] = (maxa, suma, count)
print(info[1][0])


n = int(input())
parents = [0] + [x - 1 for x in list(map(int, input().split()))]
citizens = list(map(int, input().split()))
sz = [1] * n
for i in parents:
	sz[i] = 0
for i in range(n - 1, 0, -1):
	citizens[parents[i]] += citizens[i]
	sz[parents[i]] += sz[i]
ans = 0
for i in range(n):
	if citizens[i] % sz[i] == 0:
		ans = max(ans, citizens[i] // sz[i])
	else:
		ans = max(ans, citizens[i] // sz[i] + 1)
print(ans)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
import sys, threading
sys.setrecursionlimit(400000)
threading.stack_size(10 ** 8)

def dfs(x):
	global a, adj, l, l1
	for i in adj[x]:
		dfs(i)
		l[x] += l[i]
		a[x - 1] += a[i - 1]
		l1[x] = max(l1[x], l1[i])
	if not len(adj[x]):
		l[x] = 1
		l1[x] = a[x - 1]
	else:
		c = (a[x - 1] + l[x] - 1) // l[x]
		l1[x] = max(l1[x], c)

def main():
	global a, adj, l, l1
	n = int(input())
	p = list(map(int, input().split()))
	a = list(map(int, input().split()))
	adj = [[] for i in range(n + 1)]
	l = [0] * (n + 1)
	l1 = [0] * (n + 1)
	for i in range(n - 1):
		adj[p[i]].append(i + 2)
	dfs(1)
	print(l1[1])
t = threading.Thread(target=main)
t.start()
t.join()


import os
import sys
import math
from io import BytesIO, IOBase
from fractions import Fraction
import collections
from itertools import permutations
from collections import defaultdict
from collections import deque
import threading
sys.setrecursionlimit(300000)
threading.stack_size(10 ** 8)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class Factorial:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorials = [1, 1]
		self.invModulos = [0, 1]
		self.invFactorial_ = [1, 1]

	def calc(self, n):
		if n <= -1:
			print('Invalid argument to calculate n!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.factorials):
			return self.factorials[n]
		nextArr = [0] * (n + 1 - len(self.factorials))
		initialI = len(self.factorials)
		prev = self.factorials[-1]
		m = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * i % m
		self.factorials += nextArr
		return self.factorials[n]

	def inv(self, n):
		if n <= -1:
			print('Invalid argument to calculate n^(-1)')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		p = self.MOD
		pi = n % p
		if pi < len(self.invModulos):
			return self.invModulos[pi]
		nextArr = [0] * (n + 1 - len(self.invModulos))
		initialI = len(self.invModulos)
		for i in range(initialI, min(p, n + 1)):
			next = -self.invModulos[p % i] * (p // i) % p
			self.invModulos.append(next)
		return self.invModulos[pi]

	def invFactorial(self, n):
		if n <= -1:
			print('Invalid argument to calculate (n^(-1))!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.invFactorial_):
			return self.invFactorial_[n]
		self.inv(n)
		nextArr = [0] * (n + 1 - len(self.invFactorial_))
		initialI = len(self.invFactorial_)
		prev = self.invFactorial_[-1]
		p = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * self.invModulos[i % p] % p
		self.invFactorial_ += nextArr
		return self.invFactorial_[n]

class Combination:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorial = Factorial(MOD)

	def ncr(self, n, k):
		if k < 0 or n < k:
			return 0
		k = min(k, n - k)
		f = self.factorial
		return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

def main():
	n = int(input())
	p = list(map(int, input().split()))
	a = list(map(int, input().split()))
	d = defaultdict(list)
	for i in range(n - 1):
		d[p[i]].append(i + 2)
	leaf = [0] * n
	people = [0] * n

	def dfs(i):
		l = 0
		p = a[i - 1]
		if len(d[i]) == 0:
			people[i - 1] = a[i - 1]
			leaf[i - 1] = 1
			return (1, a[i - 1])
		else:
			for j in d[i]:
				(cl, cp) = dfs(j)
				l += cl
				p += cp
			people[i - 1] = p
			leaf[i - 1] = l
			return (l, p)
	dfs(1)
	m = 0
	for i in range(n):
		m = max(m, math.ceil(people[i] / leaf[i]))
	print(m)
t = threading.Thread(target=main)
t.start()
t.join()


import os
import sys
from io import BytesIO, IOBase
_str = str
BUFSIZE = 8192

def str(x=b''):
	return x if type(x) is bytes else _str(x).encode()

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def inp():
	return sys.stdin.readline().rstrip()

def mpint():
	return map(int, inp().split(' '))

def itg():
	return int(inp())

def tree_bfs(tree, start=0, flat=True) -> list:
	stack = [start]
	result = []
	while stack:
		new_stack = []
		if flat:
			result.extend(stack)
		else:
			result.append(stack)
		for node in stack:
			new_stack.extend(tree[node])
		stack = new_stack
	return result

def to_tree(graph, root=0):
	stack = [[root]]
	while stack:
		if not stack[-1]:
			del stack[-1]
			continue
		parent = stack[-1].pop()
		for child in graph[parent]:
			graph[child].discard(parent)
		stack.append(list(graph[parent]))

def node_leaves(tree):
	n = len(tree)
	leaf = {i for i in range(n) if not tree[i]}
	result = [0] * n
	for i in tree_postorder(tree):
		result[i] += sum(map(result.__getitem__, tree[i])) + len(tree[i] & leaf)
	return result

def get_parent_list(tree):
	result = [0] * len(tree)
	for (parent, children) in enumerate(tree):
		for child in children:
			result[child] = parent
	return result

def tree_postorder(tree, root=0, flat=True):
	return tree_bfs(tree, root, flat=flat)[::-1]

def ceil_a_divide_b(a, b):
	if a > 0 and b < 0:
		(a, b) = (-a, -b)
	return (a - 1) // b + 1

def solve():
	n = itg()
	tree = [set() for _ in range(n)]
	for (i, j) in enumerate(mpint(), 1):
		j -= 1
		tree[i].add(j)
		tree[j].add(i)
	to_tree(tree)
	values = list(mpint())
	leaves = node_leaves(tree)
	parents = get_parent_list(tree)
	ans = 0
	for i in tree_postorder(tree):
		if leaves[i] == 0:
			ans = max(ans, values[i])
		else:
			ans = max(ans, ceil_a_divide_b(values[i], leaves[i]))
		values[parents[i]] += values[i]
	return ans

def main():
	print(solve())
DEBUG = 0
URL = 'https://codeforces.com/contest/1436/problem/D'
if DEBUG == 1:
	import requests
	from ACgenerator.Y_Test_Case_Runner import TestCaseRunner
	runner = TestCaseRunner(main, URL)
	inp = runner.input_stream
	print = runner.output_stream
	runner.checking()
elif DEBUG == 2:
	main()
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
	main()


import sys, io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
n = int(input())
child = [[] for _ in range(n)]
par = [-1] + list(map(lambda x: int(x) - 1, input().split()))
for i in range(1, n):
	child[par[i]].append(i)
pop = list(map(int, input().split()))
end = [0] * n
stack = [0]
while stack:
	if len(child[stack[-1]]) == 0:
		v = stack.pop()
		if end[v] == 0:
			end[v] = 1
		if v:
			p = stack[-1]
			end[p] += end[v]
			pop[p] += pop[v]
		continue
	else:
		stack.append(child[stack[-1]].pop())
out = [(p + e - 1) // e for (e, p) in zip(end, pop)]
print(max(out))


import math
import os
import sys
from io import BytesIO, IOBase
import math
from collections import defaultdict
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from collections import Counter, defaultdict, deque
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc
sys.setrecursionlimit(200010)

@bootstrap
def dfs(u):
	global m
	if vis[u] == 1:
		yield
	vis[u] = 1
	totleaf = 0
	for j in adj[u]:
		if vis[j] == 0:
			yield dfs(j)
			b[u - 1] += b[j - 1]
			cnt[u] += cnt[j]
	if adj[u] == []:
		cnt[u] = 1
		yield
	yield
n = int(input())
p = list(map(int, input().split()))
b = list(map(int, input().split()))
adj = [[] for i in range(n + 1)]
for j in range(n - 1):
	adj[p[j]].append(j + 2)
cnt = [0 for i in range(n + 1)]
vis = [0] * (n + 1)
dfs(1)
m = 0
for j in range(1, n + 1):
	if cnt[j]:
		m = max(m, math.ceil(b[j - 1] / cnt[j]))
print(m)


from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc
n = int(input())
adj = [[] for _ in range(n + 1)]
arr = [int(x) for x in input().split()]
for i in range(n - 1):
	adj[arr[i]].append(i + 2)
nCitizens = [0] + [int(x) for x in input().split()]

@bootstrap
def dfs(node):
	subtreeCitizenCnt = nCitizens[node]
	subtreeLeafCnt = 0
	if len(adj[node]) == 0:
		isLeaf = True
	else:
		isLeaf = False
	if isLeaf:
		subtreeLeafCnt += 1
	else:
		for child in adj[node]:
			(c, l) = (yield dfs(child))
			subtreeCitizenCnt += c
			subtreeLeafCnt += l
	mostPopulousLeafSize = subtreeCitizenCnt // subtreeLeafCnt
	if subtreeCitizenCnt % subtreeLeafCnt != 0:
		mostPopulousLeafSize += 1
	ans[0] = max(ans[0], mostPopulousLeafSize)
	yield [subtreeCitizenCnt, subtreeLeafCnt]
ans = [0]
dfs(1)
print(ans[0])


import sys
input = sys.stdin.readline
import math
n = int(input())
P = [1] + list(map(int, input().split()))
A = list(map(int, input().split()))
for i in range(n):
	P[i] -= 1
Y = [1] * n
for i in range(n):
	Y[P[i]] = 0
for i in range(n - 1, 0, -1):
	Y[P[i]] += Y[i]
S = [a for a in A]
for i in range(n - 1, 0, -1):
	S[P[i]] += S[i]
ans = 0
for i in range(n):
	ans = max(ans, math.ceil(S[i] / Y[i]))
print(ans)


import sys, io, os
BUFSIZE = 8192

class FastIO(io.IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = io.BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(io.IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
N = int(input())
P = [-100] + [int(i) - 1 for i in input().split()]
A = list(map(int, input().split()))
Size = [-1] * N
People = A[:]
Ans = [0] * N
for i in range(N - 1, -1, -1):
	p = P[i]
	size = Size[i]
	if i != 0:
		if Size[p] == -1:
			Size[p] = 0
		if size == -1:
			Size[p] += 1
			Ans[i] = People[i]
		else:
			Size[p] += size
	people = People[i]
	ans = Ans[i]
	a = -(-people // size)
	if ans < a:
		Ans[i] = ans = a
	if i != 0:
		People[p] += people
		if Ans[p] < ans:
			Ans[p] = ans
print(Ans[0])


from collections import deque
n = int(input())
p = list(map(int, input().split()))
a = list(map(int, input().split()))
edge = [[] for i in range(n)]
for i in range(n - 1):
	edge[p[i] - 1].append(i + 1)
dp = [0 for i in range(n)]
size = [not edge[v] for v in range(n)]
res = []
deq = deque([0])
while deq:
	v = deq.popleft()
	res.append(v)
	for nv in edge[v]:
		deq.append(nv)
res = res[::-1]
for v in res:
	tmp = -1
	S = 0
	for nv in edge[v]:
		tmp = max(tmp, dp[nv])
		size[v] += size[nv]
		S += a[nv]
	if not edge[v]:
		dp[v] = a[v]
		continue
	rest = tmp * size[v] - S
	if a[v] <= rest:
		dp[v] = tmp
	else:
		q = (a[v] - rest) // size[v]
		r = (a[v] - rest) % size[v]
		if r:
			dp[v] = tmp + q + 1
		else:
			dp[v] = tmp + q
	a[v] += S
print(dp[0])


from math import factorial, ceil
from sys import stdin, stdout
from collections import defaultdict

def DFS(parent, children, citz, n):
	maxes = defaultdict(lambda : 0)
	count = defaultdict(lambda : 0)
	for i in reversed(range(2, n + 1)):
		if children[i] == 0:
			count[i] = 1
			maxes[i] = citz[i - 1]
			count[parent[i]] += count[i]
			citz[parent[i] - 1] += citz[i - 1]
			maxes[parent[i]] = max(maxes[parent[i]], maxes[i])
		else:
			count[parent[i]] += count[i]
			citz[parent[i] - 1] += citz[i - 1]
			maxes[i] = max(maxes[i], ceil(citz[i - 1] / count[i]))
			maxes[parent[i]] = max(maxes[parent[i]], maxes[i])
	stdout.write(str(max(maxes[1], ceil(citz[0] / count[1]))))

def main():
	n = int(stdin.readline())
	arr = list(map(int, stdin.readline().split()))
	citz = list(map(int, stdin.readline().split()))
	parent = {}
	children = defaultdict(lambda : 0)
	for i in range(len(arr)):
		parent[i + 2] = arr[i]
		children[arr[i]] += 1
	DFS(parent, children, citz, n)
main()


import sys
from collections import deque
input = sys.stdin.buffer.readline
n = int(input())
e = [[] for _ in range(n + 1)]
ls = list(map(int, input().split()))
for (i, u) in enumerate(ls):
	e[u].append(i + 2)
pp = [0] + list(map(int, input().split()))
(q, order, par) = (deque([1]), [], [0] * (n + 1))
while q:
	u = q.popleft()
	order.append(u)
	for v in e[u]:
		if v == par[u]:
			continue
		par[v] = u
		q.append(v)
(leaf, cc) = ([0] * (n + 1), 0)
for u in reversed(order):
	lcc = 0
	for v in e[u]:
		if v == par[u]:
			continue
		lcc += leaf[v]
		pp[u] += pp[v]
	lcc = max(1, lcc)
	leaf[u] = lcc
	cc = max(cc, (pp[u] + lcc - 1) // lcc)
print(cc)


from collections import defaultdict
import sys, threading
sys.setrecursionlimit(500000)
threading.stack_size(134217728)

def solve():

	def dfs(node, visited):
		visited[node - 1] = 1
		s = a[node - 1]
		c = 0
		m = -1
		for no in g[node]:
			if visited[no - 1] == 0:
				p = dfs(no, visited)
				s = s + p[0]
				c = c + p[1]
				m = max(m, p[2])
		if g[node] == []:
			c = c + 1
		q = (s + c - 1) // c
		if q > m:
			m = q
		return (s, c, m)
	n = int(input())
	p = list(map(int, sys.stdin.readline().split()))
	a = list(map(int, sys.stdin.readline().split()))
	g = defaultdict(list)
	for j in range(n - 1):
		g[p[j]].append(j + 2)
	visited = [0] * n
	an = dfs(1, visited)
	print(an[2])
threading.Thread(target=solve).start()


import sys, math
import io, os
from bisect import bisect_left as bl, bisect_right as br, insort
from heapq import heapify, heappush, heappop
from collections import defaultdict as dd, deque, Counter
from itertools import permutations, combinations

def data():
	return sys.stdin.readline().strip()

def mdata():
	return list(map(int, data().split()))

def outl(var):
	sys.stdout.write(' '.join(map(str, var)) + '\n')

def out(var):
	sys.stdout.write(str(var) + '\n')
INF = float('inf')
mod = int(1000000000.0) + 7

def dfs(graph, start=0):
	n = len(graph)
	dp = [[0, a[i], 0] for i in range(n)]
	(visited, finished) = ([False] * n, [False] * n)
	stack = [start]
	while stack:
		start = stack[-1]
		if not visited[start]:
			visited[start] = True
			for child in graph[start]:
				if not visited[child]:
					stack.append(child)
		else:
			stack.pop()
			if start != 0 and len(graph[start]) == 1:
				dp[start][0] = 1
				dp[start][2] = a[start]
			for child in graph[start]:
				if finished[child]:
					dp[start][0] += dp[child][0]
					dp[start][1] += dp[child][1]
					dp[start][2] = max(dp[start][2], dp[child][2])
			dp[start][2] = max(dp[start][2], dp[start][1] // dp[start][0] + (1 if dp[start][1] % dp[start][0] else 0))
			finished[start] = True
	return dp[0][2]
n = int(data())
graph = [[] for i in range(n)]
p = mdata()
for i in range(n - 1):
	graph[i + 1].append(p[i] - 1)
	graph[p[i] - 1].append(i + 1)
a = mdata()
out(dfs(graph, 0))


n = int(input())
parents = [0] + [x - 1 for x in list(map(int, input().split()))]
citizens = list(map(int, input().split()))
size = [1] * n
for i in parents:
	size[i] = 0
for i in range(n - 1, 0, -1):
	citizens[parents[i]] += citizens[i]
	size[parents[i]] += size[i]
ans = 0
for i in range(n):
	ans = max(ans, (citizens[i] + size[i] - 1) // size[i])
print(ans)


from collections import defaultdict, deque
from math import ceil
from sys import setrecursionlimit
import io, os
setrecursionlimit(300000)
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
n = int(input())
par = [-1] + list(map(int, input().split()))
_g = defaultdict(list)
real_leaves = set(range(n))
people = list(map(int, input().split()))
children = [0] * (n + 1)
for (i, v) in enumerate(par):
	real_leaves.discard(v - 1)
	_g[i].append(v - 1)
	children[v - 1] += 1
q = deque(real_leaves)
(leaves, people_cnt) = ([0] * (n + 1), people[:])
for i in real_leaves:
	leaves[i] = 1
ans = 0
while True:
	q2 = deque()
	while q:
		now = q.popleft()
		ans = max(ans, ceil(people_cnt[now] / leaves[now]))
		for par in _g[now]:
			leaves[par] += leaves[now]
			people_cnt[par] += people_cnt[now]
			children[par] -= 1
			if children[par] == 0:
				q2.append(par)
	if not q2:
		break
	q = q2
print(ans)


from bisect import bisect_left as bl
from bisect import bisect_right as br
from heapq import heappush, heappop
import math
from collections import *
from functools import reduce, cmp_to_key
import sys
input = sys.stdin.readline
M = mod = 998244353

def factors(n):
	return sorted(set(reduce(list.__add__, ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0))))

def inv_mod(n):
	return pow(n, mod - 2, mod)

def li():
	return [int(i) for i in input().rstrip('\n').split()]

def st():
	return input().rstrip('\n')

def val():
	return int(input().rstrip('\n'))

def li2():
	return [i for i in input().rstrip('\n')]

def li3():
	return [int(i) for i in input().rstrip('\n')]
n = val()
parents = [1, 1] + li()
values = [0] + li()
sizes = [1] * (n + 5)
for i in range(2, n + 1, 1):
	sizes[parents[i]] = 0
ans = -float('inf')
for i in range(n, 0, -1):
	ans = max(ans, (values[i] + sizes[i] - 1) / sizes[i])
	values[parents[i]] += values[i]
	sizes[parents[i]] += sizes[i]
print(int(ans))


import sys
import threading
from sys import stdin, stdout
sys.setrecursionlimit(10 ** 9)
threading.stack_size(16 * 2048 * 2048)

def bandit_in_a_city(n, dic, a_a):
	r_a = dfs(1, -1, dic, a_a)
	return r_a[0]

def dfs(sq, fr, dic, a_a):
	w = a_a[sq - 1]
	res = []
	if sq in dic:
		for nxt in dic[sq]:
			if nxt != fr:
				r = dfs(nxt, sq, dic, a_a)
				if res:
					if res[0] < r[0]:
						res[1] += r[1] + (r[0] - res[0]) * res[2]
						res[0] = r[0]
					else:
						res[1] += r[1] + (res[0] - r[0]) * r[2]
					res[2] += r[2]
				else:
					res = r
	if res:
		if res[1] >= w:
			res[1] -= w
		else:
			a = w - res[1]
			b = a // res[2]
			c = a % res[2]
			res[0] += b
			if c > 0:
				res[0] += 1
				res[1] = res[2] - c
			else:
				res[1] = 0
		return res
	else:
		return [w, 0, 1]

def solve():
	n = int(stdin.readline())
	p_a = list(map(int, stdin.readline().split()))
	a_a = list(map(int, stdin.readline().split()))
	dic = {}
	for i in range(len(p_a)):
		if p_a[i] not in dic:
			dic[p_a[i]] = []
		dic[p_a[i]].append(i + 2)
	res = bandit_in_a_city(n, dic, a_a)
	stdout.write(str(res))
threading.Thread(target=solve).start()


n = int(input())
a = [int(x) for x in input().split()]
g = [0] * n
for i in range(n - 1):
	if type(g[a[i] - 1]) == int:
		g[a[i] - 1] = []
	g[a[i] - 1].append(i + 1)
a = [int(x) for x in input().split()]
b = [0] * n
now = [0] * n
for i in range(n - 1, -1, -1):
	if g[i] == 0:
		b[i] = 1
		now[i] = a[i]
		continue
	maxi = 0
	for x in g[i]:
		b[i] += b[x]
		if a[x] < 0:
			a[i] += a[x]
			a[x] = 0
		maxi = max(maxi, now[x])
	for x in g[i]:
		a[i] -= (maxi - now[x]) * b[x]
		now[x] = maxi
	now[i] = maxi
	if a[i] < 0:
		continue
	now[i] += (a[i] + b[i] - 1) // b[i]
	a[i] -= (a[i] + b[i] - 1) // b[i] * b[i]
print(now[0])


import math, sys
from collections import defaultdict, deque
import bisect as bi

def yes():
	print('YES')

def no():
	print('NO')

def I():
	return int(sys.stdin.readline())

def In():
	return map(int, sys.stdin.readline().split())

def Sn():
	return sys.stdin.readline().strip()
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc

def dict(a):
	d = {}
	for x in a:
		if d.get(x, -1) != -1:
			d[x] += 1
		else:
			d[x] = 1
	return d

def find_gt(a, x):
	i = bi.bisect_left(a, x)
	if i != len(a):
		return i
	else:
		return -1

@bootstrap
def dfs(d, visit, node, person, ans):
	visit[node] = True
	if len(d[node]) == 1 and visit[d[node][0]] == True:
		ans.append(person[node - 1])
		yield [person[node - 1], 1]
	temp = [person[node - 1], 0]
	for x in d[node]:
		if visit[x] == False:
			z = (yield dfs(d, visit, x, person, ans))
			temp[0] += z[0]
			temp[1] += z[1]
	ans.append(math.ceil(temp[0] / temp[1]))
	yield temp

def main():
	try:
		n = I()
		l = list(In())
		d = defaultdict(list)
		for i in range(n - 1):
			d[i + 2].append(l[i])
			d[l[i]].append(i + 2)
		person = list(In())
		visit = [False for x in range(n + 1)]
		ans = []
		z = dfs(d, visit, 1, person, ans)
		ans = max(ans)
		ans = max(math.ceil(z[0] / z[1]), ans)
		print(ans)
	except:
		pass
M = 998244353
P = 1000000007
for _ in range(1):
	main()


import sys
sys.setrecursionlimit(10 ** 5)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

def II():
	return int(sys.stdin.buffer.readline())

def MI():
	return map(int, sys.stdin.buffer.readline().split())

def LI():
	return list(map(int, sys.stdin.buffer.readline().split()))

def LI1():
	return list(map(int1, sys.stdin.buffer.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def BI():
	return sys.stdin.buffer.readline().rstrip()

def SI():
	return sys.stdin.buffer.readline().rstrip().decode()
n = II()
pp = LI1()
aa = LI()
to = [[] for _ in range(n)]
for (u, p) in enumerate(pp, 1):
	to[p].append(u)
mm = [-1] * n
gg = [0] * n
ss = [-1] * n
stack = [0]
while stack:
	u = stack.pop()
	if ss[u] != -1:
		g = gg[u]
		cur = (ss[u] + g - 1) // g
		mm[u] = max(mm[u], cur)
		if u > 0:
			p = pp[u - 1]
			ss[p] += ss[u]
			gg[p] += gg[u]
			mm[p] = max(mm[p], mm[u])
	else:
		ss[u] = aa[u]
		if not to[u]:
			mm[u] = aa[u]
			gg[u] = 1
		stack.append(u)
		for v in to[u]:
			stack.append(v)
print(mm[0])


from math import ceil

def bfs(dec, leaves, start, mem):
	if start in mem:
		return mem[start]
	result = 0
	for j in dec[start]:
		if j in leaves:
			result += 1
		else:
			result += bfs(dec, leaves, j, mem)
	mem[start] = result
	return result
n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
dec = {}
leaves = {}
for i in range(n - 1):
	if a[i] in dec:
		dec[a[i]].append(i + 2)
	else:
		dec[a[i]] = [i + 2]
for i in range(1, n + 1):
	if i not in dec:
		leaves[i] = 1
leaves_f = {}
parent = [0] + [j - 1 for j in a]
ans = 0
laves_fin = [1] * n
for i in range(1, n):
	laves_fin[parent[i]] = 0
for i in range(n - 1, 0, -1):
	b[parent[i]] += b[i]
	laves_fin[parent[i]] += laves_fin[i]
for i in range(n):
	ans = max(ans, ceil(b[i] / laves_fin[i]))
print(ans)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
n = int(input())
p = [0] + [x - 1 for x in list(map(int, input().split()))]
resident = list(map(int, input().split()))
s = [1] * n
for i in p:
	s[i] = 0
for i in range(n - 1, 0, -1):
	resident[p[i]] += resident[i]
	s[p[i]] += s[i]
ans = 0
for i in range(0, n):
	ans = max(ans, (resident[i] + s[i] - 1) // s[i])
print(ans)


n = int(input())
P = [-1] + list(map(lambda x: int(x) - 1, input().split()))
A = list(map(int, input().split()))
ans = 0
C = [[] for i in range(n)]
for i in range(1, n):
	C[P[i]] += [i]
que = [0]
B = [0] * n
for i in range(n):
	if not C[i]:
		B[i] = 1
while que:
	q = que.pop()
	if C[q]:
		que += [C[q].pop()]
	else:
		ans = max(ans, (A[q] - 1) // B[q] + 1)
		if q == 0:
			break
		B[P[q]] += B[q]
		A[P[q]] += A[q]
		que += [P[q]]
print(ans)


from __future__ import division, print_function
from fractions import Fraction
import sys
import os
from io import BytesIO, IOBase
from itertools import *
import bisect
from heapq import *
from math import ceil, floor
from copy import *
from collections import deque, defaultdict
from collections import Counter as counter
from itertools import combinations
from itertools import permutations as permutate
from bisect import bisect_left as bl
from operator import *
from bisect import bisect_right as br
from bisect import bisect
BUFSIZE = 8192
from sys import stderr

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
from types import GeneratorType

def iterative(f, stack=[]):

	def wrapped_func(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		to = f(*args, **kwargs)
		while True:
			if type(to) is GeneratorType:
				stack.append(to)
				to = next(to)
				continue
			stack.pop()
			if not stack:
				break
			to = stack[-1].send(to)
		return to
	return wrapped_func
mod = 1000000007

def inp():
	return sys.stdin.readline().rstrip('\r\n')

def out(var):
	sys.stdout.write(str(var))

def lis():
	return list(map(int, inp().split()))

def stringlis():
	return list(map(str, inp().split()))

def sep():
	return map(int, inp().split())

def strsep():
	return map(str, inp().split())

def fsep():
	return map(float, inp().split())

def nextline():
	out('\n')

def testcase(t):
	for p in range(t):
		solve()

def pow(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res
from functools import reduce

def factors(n):
	return set(reduce(list.__add__, ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0)))

def lcm(a, b):
	return abs(a // gcd(a, b) * b)

def gcd(a, b):
	if a == b:
		return a
	while b > 0:
		(a, b) = (b, a % b)
	return a

def comb(n, r):
	if n < r:
		return 0
	else:
		return fac[n] * (finv[r] * finv[n - r] % mod) % mod

def prefix_sum(ar):
	return list(accumulate(ar))

def suffix_sum(ar):
	return list(accumulate(ar[::-1]))[::-1]

def N():
	return int(inp())
from collections import defaultdict

def numberOfSetBits(i):
	i = i - (i >> 1 & 1431655765)
	i = (i & 858993459) + (i >> 2 & 858993459)
	return ((i + (i >> 4) & 252645135) * 16843009 & 4294967295) >> 24

def yes():
	print('Yes')

def no():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')

def solve():
	n = N()
	ar = lis()
	g = [[] for _ in range(n + 1)]
	for i in range(1, n):
		g[ar[i - 1]].append(i + 1)
	people = lis()
	dp1 = [0] * (n + 1)
	dp2 = [0] * (n + 1)

	@iterative
	def dfs1(v):
		if len(g[v]) == 0:
			dp1[v] = 1
			dp2[v] = people[v - 1]
			yield
		dp2[v] = people[v - 1]
		for c in g[v]:
			yield dfs1(c)
			dp1[v] += dp1[c]
			dp2[v] += dp2[c]
		yield
	temp = []
	dfs1(1)
	for i in range(1, n + 1):
		temp.append(ceil(dp2[i] / dp1[i]))
	print(max(temp))
solve()


import sys
input = sys.stdin.readline
n = int(input())
P = [1] + list(map(int, input().split()))
A = list(map(int, input().split()))
for i in range(n):
	P[i] -= 1
Y = [1] * n
for i in range(n):
	Y[P[i]] = 0
for i in range(n - 1, 0, -1):
	Y[P[i]] += Y[i]
S = [a for a in A]
for i in range(n - 1, 0, -1):
	S[P[i]] += S[i]
OK = sum(A)
NG = -1
while OK - NG > 1:
	mid = (OK + NG) // 2
	for i in range(n):
		if Y[i] * mid < S[i]:
			NG = mid
			break
	else:
		OK = mid
print(OK)


import sys
import math
import heapq
import bisect
from collections import Counter
from collections import defaultdict
from io import BytesIO, IOBase
import string

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		import os
		self.os = os
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None
		self.BUFSIZE = 8192

	def read(self):
		while True:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, self.BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, self.BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			self.os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def get_int():
	return int(input())

def get_ints():
	return list(map(int, input().split(' ')))

def get_int_grid(n):
	return [get_ints() for _ in range(n)]

def get_str():
	return input().split(' ')

def yes_no(b):
	if b:
		return 'YES'
	else:
		return 'NO'

def binary_search(good, left, right, delta=1, right_true=False):
	limits = [left, right]
	while limits[1] - limits[0] > delta:
		if delta == 1:
			mid = sum(limits) // 2
		else:
			mid = sum(limits) / 2
		if good(mid):
			limits[int(right_true)] = mid
		else:
			limits[int(~right_true)] = mid
	if good(limits[int(right_true)]):
		return limits[int(right_true)]
	else:
		return False

def prefix_sums(a, drop_zero=False):
	p = [0]
	for x in a:
		p.append(p[-1] + x)
	if drop_zero:
		return p[1:]
	else:
		return p

def prefix_mins(a, drop_zero=False):
	p = [float('inf')]
	for x in a:
		p.append(min(p[-1], x))
	if drop_zero:
		return p[1:]
	else:
		return p

def solve_a():
	n = get_int()
	p = get_ints()
	a = get_ints()
	leaves = set(range(1, n + 1)).difference(set(p))
	downstream_leaves = {node: int(node in leaves) for node in range(1, n + 1)}
	downstream_weights = {node: a[node - 1] for node in range(1, n + 1)}
	for i in range(n - 2, -1, -1):
		downstream_leaves[p[i]] += downstream_leaves[i + 2]
		downstream_weights[p[i]] += downstream_weights[i + 2]
	return max([math.ceil(downstream_weights[i] / downstream_leaves[i]) for i in range(1, n + 1)])
print(solve_a())


import math

class Node:

	def __init__(self, num):
		self.num = num
		self.children = []
		self.citizen = 0
		self.lv_count = 0
		self.node_sum = 0
		self.score = None
		self.results = []

	def cal_score(self):
		state_stack = [(None, self)]
		while state_stack:
			(parent, cur) = state_stack[-1]
			if len(cur.results) != len(cur.children):
				for child in cur.children:
					state_stack.append((cur, child))
				continue
			state_stack.pop()
			if not cur.children:
				cur.lv_count = 1
				cur.node_sum = cur.citizen
				cur.score = cur.citizen
			else:
				max_child = None
				child_lv_count = 0
				child_node_sum = 0
				for child in cur.results:
					child_score = child.score
					if max_child is None:
						max_child = child_score
					max_child = max(max_child, child_score)
					child_lv_count += child.lv_count
					child_node_sum += child.node_sum
				cur.lv_count = child_lv_count
				cur.node_sum = child_node_sum + cur.citizen
				cap = max_child * cur.lv_count
				if cap - cur.node_sum >= 0:
					cur.score = max_child
				else:
					cur.score = math.ceil(cur.node_sum * 1.0 / cur.lv_count)
			if parent is not None:
				parent.results.append(cur)
		return self.score
n = int(input())
nodes = {}
for i in range(1, n + 1):
	nodes[i] = Node(i)
parent_nums = input().split()
citizens = input().split()
for (i, citizen) in enumerate(citizens):
	node_num = i + 1
	nodes[node_num].citizen = int(citizen)
	if node_num >= 2:
		nodes[int(parent_nums[node_num - 2])].children.append(nodes[node_num])
print(nodes[1].cal_score())


from sys import stdin
from itertools import repeat

def main():
	n = int(stdin.readline())
	p = list(map(int, stdin.readline().split(), repeat(10, n - 1)))
	a = list(map(int, stdin.readline().split(), repeat(10, n)))
	l = [1] * n
	b = [0] * n
	ans = 0
	for i in range(n - 1, -1, -1):
		b[i] += l[i]
		(x, y) = divmod(a[i], b[i])
		if y:
			x += 1
		if ans < x:
			ans = x
		if i:
			x = p[i - 1] - 1
			a[x] += a[i]
			l[x] = 0
			b[x] += b[i]
	print(ans)
main()


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline()

def RL():
	return map(int, sys.stdin.readline().split())

def RLL():
	return list(map(int, sys.stdin.readline().split()))

def N():
	return int(input())

def print_list(l):
	print(' '.join(map(str, l)))
from collections import deque as dq
from math import ceil, floor, sqrt
n = N()
father = [0, 0] + RLL()
a = [0] + RLL()
gress = [0] * (n + 1)
for i in father:
	gress[i] += 1
leaf = []
for i in range(1, n + 1):
	if not gress[i]:
		leaf.append(i)
c = [[] for _ in range(n + 1)]
while leaf:
	node = leaf.pop()
	f = father[node]
	if not c[node]:
		c[f].append((a[node], 0, 1))
	else:
		m = max((t[0] for t in c[node]))
		now = a[node]
		k = 0
		count = 0
		for t in c[node]:
			count += t[2]
			if t[0] < m:
				k += t[1] + (m - t[0]) * t[2]
			else:
				k += t[1]
		if now <= k:
			k -= now
		else:
			now -= k
			delta = now // count
			r = now % count
			if r == 0:
				m += delta
				k = 0
			else:
				m += delta + 1
				k = count - r
		c[f].append((m, k, count))
	gress[f] -= 1
	if gress[f] == 0:
		leaf.append(f)
print(c[0][0][0])


import math
n = int(input())
cities = [0 for _ in range(n + 1)]
x = list(map(int, input().split(' ')))
total = [0] + list(map(int, input().split(' ')))
ans = 0
for i in range(n, 0, -1):
	if cities[i] == 0:
		cities[i] = 1
	if i >= 2:
		cities[x[i - 2]] += cities[i]
		total[x[i - 2]] += total[i]
	ans = max(ans, math.ceil(total[i] / cities[i]))
print(ans)


import math
n = int(input())
paths = [[] for _ in range(n)]
for (i, p_i) in enumerate(map(int, input().split())):
	paths[p_i - 1].append(i + 1)
num_citizens = [int(i) for i in input().split()]
num_leaves = [None] * n
max_leaf = [None] * n
extra_space = [None] * n
for node in range(n - 1, -1, -1):
	if not paths[node]:
		num_leaves[node] = 1
		max_leaf[node] = num_citizens[node]
		extra_space[node] = 0
	else:
		num_leaves[node] = 0
		max_leaf[node] = max((max_leaf[child] for child in paths[node]))
		extra_space[node] = -num_citizens[node]
		for child in paths[node]:
			num_leaves[node] += num_leaves[child]
			extra_space[node] += extra_space[child]
			if max_leaf[child] < max_leaf[node]:
				extra_space[node] += num_leaves[child] * (max_leaf[node] - max_leaf[child])
		if extra_space[node] < 0:
			amount_increase = math.ceil(-extra_space[node] / num_leaves[node])
			max_leaf[node] += amount_increase
			extra_space[node] += amount_increase * num_leaves[node]
print(max_leaf[0])


n = int(input())
deg = [0 for _ in range(n)]
p = list(map(int, input().split()))
for i in range(n - 1):
	p[i] -= 1
	deg[p[i]] += 1
a = list(map(int, input().split()))
sz = [0 if deg[i] else 1 for i in range(n)]
ans = 0
for i in range(n - 1, 0, -1):
	sz[p[i - 1]] += sz[i]
	a[p[i - 1]] += a[i]
	ans = max(ans, (a[i] + sz[i] - 1) // sz[i])
ans = max(ans, (a[0] + sz[0] - 1) // sz[0])
print(ans)


import sys
from array import array

def input():
	return sys.stdin.buffer.readline().decode('utf-8')
n = int(input())
parent = [-1] * n
outdeg = [10 ** 9] + [0] * (n - 1)
leaf = [1] * n
for (v, u) in enumerate(map(lambda x: int(x) - 1, input().split()), start=1):
	parent[v] = u
	outdeg[u] += 1
	leaf[u] = 0
citizens = list(map(int, input().split()))
stack = [i for i in range(n) if leaf[i]]
ans = 0
while stack:
	v = stack.pop()
	ans = max(ans, (citizens[v] + leaf[v] - 1) // leaf[v])
	par = parent[v]
	citizens[par] += citizens[v]
	leaf[par] += leaf[v]
	outdeg[par] -= 1
	if outdeg[par] == 0:
		stack.append(par)
ans = max(ans, (citizens[0] + leaf[0] - 1) // leaf[0])
print(ans)


import sys, io, os
BUFSIZE = 8192

class FastIO(io.IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = io.BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(io.IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from collections import Counter, defaultdict, deque
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc
sys.setrecursionlimit(200010)
from math import ceil
n = int(input())
g = {i: [] for i in range(n)}
cnt = {i: 0 for i in range(n)}
leaves = {i: 0 for i in range(n)}
x = list(map(int, input().split()))
idx = 1
for y in x:
	g[y - 1].append(idx)
	idx += 1
leaves = list(map(int, input().split()))

@bootstrap
def dfs(u):
	if len(g[u]) == 0:
		cnt[u] = 1
		yield
	for child in g[u]:
		yield dfs(child)
		leaves[u] += leaves[child]
		cnt[u] += cnt[child]
	yield
dfs(0)
ans = 0
for i in range(n):
	ans = max(ans, ceil(leaves[i] / float(cnt[i])))
print(int(ans))


from collections import defaultdict
from math import ceil
from sys import stdin, setrecursionlimit
input = stdin.readline
setrecursionlimit(10 ** 6)
import threading
blanck = []

def dfs(node, g, parent, person, sub, leaf):
	sub[node] = person[node]
	leaf[node] = len(g[node]) == 0
	for i in g[node]:
		if i == parent:
			continue
		dfs(i, g, node, person, sub, leaf)
		sub[node] += sub[i]
		leaf[node] += leaf[i]

def main():
	n = int(input())
	p = [*map(int, input().strip().split())]
	person = [*map(int, input().strip().split())]
	g = defaultdict(list)
	person = [0] + person
	for i in range(len(p)):
		t = i + 2
		g[p[i]].append(t)
	leaf = [0] * (n + 1)
	sub = [0] * (n + 1)
	ans = 0
	dfs(1, g, -1, person, sub, leaf)
	for i in range(1, n + 1):
		if leaf[i]:
			ans = max(ans, ceil(sub[i] / leaf[i]))
	print(ans)
threading.stack_size(10 ** 8)
t = threading.Thread(target=main)
t.start()
t.join()


import os
import sys
import math
from io import BytesIO, IOBase
from fractions import Fraction
import collections
from itertools import permutations
from collections import defaultdict
from collections import deque
import threading
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class Factorial:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorials = [1, 1]
		self.invModulos = [0, 1]
		self.invFactorial_ = [1, 1]

	def calc(self, n):
		if n <= -1:
			print('Invalid argument to calculate n!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.factorials):
			return self.factorials[n]
		nextArr = [0] * (n + 1 - len(self.factorials))
		initialI = len(self.factorials)
		prev = self.factorials[-1]
		m = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * i % m
		self.factorials += nextArr
		return self.factorials[n]

	def inv(self, n):
		if n <= -1:
			print('Invalid argument to calculate n^(-1)')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		p = self.MOD
		pi = n % p
		if pi < len(self.invModulos):
			return self.invModulos[pi]
		nextArr = [0] * (n + 1 - len(self.invModulos))
		initialI = len(self.invModulos)
		for i in range(initialI, min(p, n + 1)):
			next = -self.invModulos[p % i] * (p // i) % p
			self.invModulos.append(next)
		return self.invModulos[pi]

	def invFactorial(self, n):
		if n <= -1:
			print('Invalid argument to calculate (n^(-1))!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.invFactorial_):
			return self.invFactorial_[n]
		self.inv(n)
		nextArr = [0] * (n + 1 - len(self.invFactorial_))
		initialI = len(self.invFactorial_)
		prev = self.invFactorial_[-1]
		p = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * self.invModulos[i % p] % p
		self.invFactorial_ += nextArr
		return self.invFactorial_[n]

class Combination:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorial = Factorial(MOD)

	def ncr(self, n, k):
		if k < 0 or n < k:
			return 0
		k = min(k, n - k)
		f = self.factorial
		return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

def dfs(graph, alpha, a):
	n = len(graph)
	visited = [False] * n
	finished = [False] * n
	dp = [0] * n
	leaves = [0] * n
	stack = [alpha]
	while stack:
		v = stack[-1]
		if not visited[v]:
			visited[v] = True
			for u in graph[v]:
				if not visited[u]:
					stack.append(u)
		else:
			stack.pop()
			if not graph[v]:
				leaves[v] += 1
			dp[v] += a[v - 1]
			for child in graph[v]:
				if finished[child]:
					dp[v] += dp[child]
					leaves[v] += leaves[child]
			finished[v] = True
	return (leaves, dp)
for _ in range(int(input()) if not True else 1):
	n = int(input())
	p = list(map(int, input().split()))
	a = list(map(int, input().split()))
	graph = [[] for __ in range(n + 1)]
	for i in range(n - 1):
		graph[p[i]] += [i + 2]
	(leaves, dp) = dfs(graph, 1, a)
	ans = 0
	for i in range(1, n + 1):
		ans = max(ans, math.ceil(dp[i] / leaves[i]))
	print(ans)


n = int(input())
g = [[] for i in range(n + 1)]
p = list(map(int, input().split()))
for i in range(n - 1):
	a = i + 2
	b = p[i]
	g[a].append(b)
	g[b].append(a)
dp = [0] + list(map(int, input().split()))
count = [0] * (n + 1)
maxi = [0] * (n + 1)
for i in range(2, n + 1):
	if len(g[i]) == 1:
		count[i] = 1
stack = []
stack.append(~1)
stack.append(1)
visit1 = [False] * (n + 1)
visit2 = [False] * (n + 1)
visit1[1] = True
while stack:
	now = stack.pop()
	if now < 0:
		now = ~now
		for next in g[now]:
			if visit2[next]:
				dp[now] += dp[next]
				count[now] += count[next]
				maxi[now] = max(maxi[now], maxi[next])
		maxi[now] = max(maxi[now], (dp[now] - 1) // count[now] + 1)
		visit2[now] = True
	else:
		for next in g[now]:
			if not visit1[next]:
				visit1[next] = True
				stack.append(~next)
				stack.append(next)
print(maxi[1])


import threading
import sys
input = sys.stdin.readline
threading.stack_size(10 ** 8)
sys.setrecursionlimit(10 ** 7)
from collections import defaultdict

def main():
	n = int(input())
	g = defaultdict(list)
	p = [0] * 2 + list(map(int, input().split()))
	for _ in range(2, 2 + n - 1):
		g[p[_]].append(_)
	a = [0] + list(map(int, input().split()))
	global res
	res = -1

	def dfs(cn, p):
		global res
		num_leaves = 0
		cost = a[cn]
		if not g[cn]:
			num_leaves += 1
		for nn in g[cn]:
			if nn != p:
				(t_num_leaves, t_cost) = dfs(nn, cn)
				num_leaves += t_num_leaves
				cost += t_cost
		res = max(res, (cost - 1) // num_leaves + 1)
		return (num_leaves, cost)
	dfs(1, -1)
	print(res)
threading.Thread(target=main).start()


import sys
input = sys.stdin.readline
n = int(input())
p = list(map(int, input().split()))
p.insert(0, 0)
for i in range(1, n):
	p[i] -= 1
a = list(map(int, input().split()))
data = [0] * n
for i in range(n):
	data[i] = [0, a[i], True]
i = n - 1
biggest = 0
while i > 0:
	prev = p[i]
	if data[i][2]:
		data[i][0] += 1
	data[prev][0] += data[i][0]
	data[prev][1] += data[i][1]
	data[prev][2] = False
	biggest = max(biggest, 1 + (data[i][1] - 1) // data[i][0])
	i -= 1
biggest = max(biggest, 1 + (data[0][1] - 1) // data[0][0])
print(biggest)


n = int(input())
P = list(map(int, input().split()))
A = list(map(int, input().split()))
g = [[] for _ in range(n)]
P = [p - 1 for p in P]
parent = [-1] * n
for (i, p) in enumerate(P):
	g[p].append(i + 1)
	parent[i + 1] = p
s = []
s.append(0)
order = []
while s:
	v = s.pop()
	order.append(v)
	for u in g[v]:
		if u != parent[v]:
			s.append(u)
C = [0] * n
L = [0] * n
order.reverse()
for v in order:
	C[v] += A[v]
	if len(g[v]) == 0:
		L[v] += 1
	if parent[v] != -1:
		C[parent[v]] += C[v]
		L[parent[v]] += L[v]
ans = -1
for v in range(n):
	ans = max(ans, (C[v] + L[v] - 1) // L[v])
print(ans)


import typing
import sys
import math
import collections
import bisect
import itertools
import heapq
import decimal
INF = 10 ** 20
MOD = 10 ** 9 + 7

def ni():
	return int(sys.stdin.buffer.readline())

def ns():
	return map(int, sys.stdin.buffer.readline().split())

def na():
	return list(map(int, sys.stdin.buffer.readline().split()))

def na1():
	return list(map(lambda x: int(x) - 1, sys.stdin.buffer.readline().split()))

def main():
	n = ni()
	p = [-INF] + na1()
	a = na()
	size = [0] * n
	sump = a.copy()
	ans = 0
	for i in range(n - 1, -1, -1):
		prnt = p[i]
		if size[i] == 0:
			ans = max(ans, a[i])
		else:
			ans = max(ans, -(-sump[i] // size[i]))
		if i != 0:
			sump[prnt] += sump[i]
			size[prnt] += size[i] if size[i] != 0 else 1
	print(ans)
main()


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from math import gcd, ceil

def prod(a, mod=10 ** 9 + 7):
	ans = 1
	for each in a:
		ans = ans * each % mod
	return ans

def lcm(a, b):
	return a * b // gcd(a, b)

def binary(x, length=16):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y

def dfs(graph, alpha, a):
	n = len(graph)
	visited = [False] * n
	finished = [False] * n
	dp = [0] * n
	leaves = [0] * n
	stack = [alpha]
	while stack:
		v = stack[-1]
		if not visited[v]:
			visited[v] = True
			for u in graph[v]:
				if not visited[u]:
					stack.append(u)
		else:
			stack.pop()
			if not graph[v]:
				leaves[v] += 1
			dp[v] += a[v - 1]
			for child in graph[v]:
				if finished[child]:
					dp[v] += dp[child]
					leaves[v] += leaves[child]
			finished[v] = True
	return (leaves, dp)
for _ in range(int(input()) if not True else 1):
	n = int(input())
	p = list(map(int, input().split()))
	a = list(map(int, input().split()))
	graph = [[] for __ in range(n + 1)]
	for i in range(n - 1):
		graph[p[i]] += [i + 2]
	(leaves, dp) = dfs(graph, 1, a)
	ans = 0
	for i in range(1, n + 1):
		ans = max(ans, ceil(dp[i] / leaves[i]))
	print(ans)


from math import ceil
from sys import stdin, stdout

def II():
	return int(stdin.readline())

def LI():
	return list(map(int, stdin.readline().split()))
n = II()
p = LI()
p = [x - 1 for x in p]
deg = [0 for i in range(n)]
leafs = [0 for i in range(n)]
maxDensity = [0 for i in range(n)]
for x in p:
	deg[x] += 1
population = LI()
for i in range(n - 1, 0, -1):
	parent = p[i - 1]
	if deg[i] == 0:
		leafs[parent] += 1
		maxDensity[i] = population[i]
	else:
		maxDensity[i] = max(maxDensity[i], ceil(population[i] / leafs[i]))
		leafs[parent] += leafs[i]
	population[parent] += population[i]
	maxDensity[parent] = max(maxDensity[parent], maxDensity[i])
ans = max(maxDensity[0], ceil(population[0] / leafs[0]))
stdout.write(str(ans) + '\n')


from math import ceil
n = int(input())
p = list(map(int, input().split()))
a = list(map(int, input().split()))
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc

class Graph:

	def __init__(self, V):
		self.V = V
		self.adj = [[] for i in range(V)]

	@bootstrap
	def DFSUtil(self, temp, v, visited, sums, maxs, counts):
		visited[v] = True
		temp.append(v)
		s = a[v]
		count = 0
		maxis = []
		for i in self.adj[v]:
			if visited[i] == False:
				temp = (yield self.DFSUtil(temp, i, visited, sums, maxs, counts))
				count += counts[i]
				maxis.append(maxs[i])
				s += sums[i]
		sums[v] = s
		if count == 0:
			count += 1
		counts[v] = count
		if len(maxis) == 0:
			maxs[v] = a[v]
		else:
			maxs[v] = max(int(ceil(sums[v] / counts[v])), max(maxis))
		yield temp

	def addEdge(self, v, w):
		self.adj[w].append(v)
G = Graph(n)
for i in range(0, len(p)):
	G.addEdge(i + 1, p[i] - 1)
visited = [False for _ in range(n)]
sums = [0 for _ in range(n)]
maxs = [0 for _ in range(n)]
counts = [0 for _ in range(n)]
G.DFSUtil([], 0, visited, sums, maxs, counts)
print(maxs[0])


n = int(input())
p = [0, 0] + list(map(int, input().split()))
a = [0] + list(map(int, input().split()))
g = [[] for _ in range(n + 1)]
slots = [0] * (n + 1)
cap = [0] * (n + 1)
leaves = [0] * (n + 1)
for u in range(n, 0, -1):
	g[p[u]].append(u)
	if not g[u]:
		cap[u] = a[u]
		leaves[u] = 1
		continue
	maxcap = cap[max(g[u], key=lambda v: cap[v])]
	slots_sum = 0
	for v in g[u]:
		slots_sum += slots[v] + leaves[v] * (maxcap - cap[v])
		leaves[u] += leaves[v]
	mn = min(slots_sum, a[u])
	slots_sum -= mn
	a[u] -= mn
	ausplit = (a[u] + leaves[u] - 1) // leaves[u]
	cap[u] = maxcap + ausplit
	slots[u] = slots_sum + ausplit * leaves[u] - a[u]
print(cap[1])


import sys
import bisect as bi
import itertools as it
import math as mt
import collections as cc
import heapq as hp
input = sys.stdin.readline
I = lambda : list(map(int, input().split()))
(n,) = I()
p = [1] + I()
ar = I()
for i in range(n):
	p[i] -= 1
sub = [1] * n
for i in range(n):
	sub[p[i]] = 0
for i in range(n - 1, 0, -1):
	sub[p[i]] += sub[i]
temp = [i for i in ar]
for i in range(n - 1, 0, -1):
	temp[p[i]] += temp[i]
high = sum(ar)
low = -1
while high - low > 1:
	mid = (low + high) // 2
	tf = 1
	for i in range(n):
		if sub[i] * mid >= temp[i]:
			pass
		else:
			tf = 0
			break
	if not tf:
		low = mid
	else:
		high = mid
print(high)


import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
n = int(input())
p = [0, 0] + list(map(int, input().split()))
a = [0] + list(map(int, input().split()))
g = [[] for _ in range(n + 1)]
up = [0] * (n + 1)
for (i, pi) in enumerate(p):
	g[pi].append(i)
	up[pi] += 1
slots = [0] * (n + 1)
cap = [0] * (n + 1)
leaves = [0] * (n + 1)
st = [u for u in range(1, n + 1) if not up[u]]
while st:
	u = st.pop()
	if not g[u]:
		cap[u] = a[u]
		leaves[u] = 1
	else:
		maxcap = cap[max(g[u], key=lambda v: cap[v])]
		slots_sum = 0
		for v in g[u]:
			slots_sum += slots[v] + leaves[v] * (maxcap - cap[v])
			leaves[u] += leaves[v]
		mn = min(slots_sum, a[u])
		slots_sum -= mn
		a[u] -= mn
		ausplit = (a[u] + leaves[u] - 1) // leaves[u]
		cap[u] = maxcap + ausplit
		slots[u] = slots_sum + ausplit * leaves[u] - a[u]
	up[p[u]] -= 1
	if not up[p[u]]:
		st.append(p[u])
print(cap[1])