Medicine faculty of Berland State University has just finished their admission campaign. As usual, about $80\%$ of applicants are girls and majority of them are going to live in the university dormitory for the next $4$ (hopefully) years.

The dormitory consists of $n$ rooms and a single mouse! Girls decided to set mouse traps in some rooms to get rid of the horrible monster. Setting a trap in room number $i$ costs $c_i$ burles. Rooms are numbered from $1$ to $n$.

Mouse doesn't sit in place all the time, it constantly runs. If it is in room $i$ in second $t$ then it will run to room $a_i$ in second $t + 1$ without visiting any other rooms inbetween ($i = a_i$ means that mouse won't leave room $i$). It's second $0$ in the start. If the mouse is in some room with a mouse trap in it, then the mouse get caught into this trap.

That would have been so easy if the girls actually knew where the mouse at. Unfortunately, that's not the case, mouse can be in any room from $1$ to $n$ at second $0$.

What it the minimal total amount of burles girls can spend to set the traps in order to guarantee that the mouse will eventually be caught no matter the room it started from?


-----Input-----

The first line contains as single integers $n$ ($1 \le n \le 2 \cdot 10^5$) — the number of rooms in the dormitory.

The second line contains $n$ integers $c_1, c_2, \dots, c_n$ ($1 \le c_i \le 10^4$) — $c_i$ is the cost of setting the trap in room number $i$.

The third line contains $n$ integers $a_1, a_2, \dots, a_n$ ($1 \le a_i \le n$) — $a_i$ is the room the mouse will run to the next second after being in room $i$.


-----Output-----

Print a single integer — the minimal total amount of burles girls can spend to set the traps in order to guarantee that the mouse will eventually be caught no matter the room it started from.


-----Examples-----
Input
5
1 2 3 2 10
1 3 4 3 3

Output
3

Input
4
1 10 2 10
2 4 2 2

Output
10

Input
7
1 1 1 1 1 1 1
2 2 2 3 6 7 6

Output
2



-----Note-----

In the first example it is enough to set mouse trap in rooms $1$ and $4$. If mouse starts in room $1$ then it gets caught immideately. If mouse starts in any other room then it eventually comes to room $4$.

In the second example it is enough to set mouse trap in room $2$. If mouse starts in room $2$ then it gets caught immideately. If mouse starts in any other room then it runs to room $2$ in second $1$.

Here are the paths of the mouse from different starts from the third example:

  $1 \rightarrow 2 \rightarrow 2 \rightarrow \dots$;  $2 \rightarrow 2 \rightarrow \dots$;  $3 \rightarrow 2 \rightarrow 2 \rightarrow \dots$;  $4 \rightarrow 3 \rightarrow 2 \rightarrow 2 \rightarrow \dots$;  $5 \rightarrow 6 \rightarrow 7 \rightarrow 6 \rightarrow \dots$;  $6 \rightarrow 7 \rightarrow 6 \rightarrow \dots$;  $7 \rightarrow 6 \rightarrow 7 \rightarrow \dots$; 

So it's enough to set traps in rooms $2$ and $6$.

Source: codeforces | Difficulty: MEDIUM_HARD
Tags: Graph algorithms

Graph traversal


Solutions:
from sys import stdin
input = lambda : stdin.readline().strip()
from math import ceil, sqrt, factorial, gcd
from collections import deque
n = int(input())
l = [0] + list(map(int, input().split()))
s = [0] + list(map(int, input().split()))
ans = 0
visited = [0] * (n + 1)
for i in range(1, n + 1):
	x = i
	while visited[x] == 0:
		visited[x] = i
		x = s[x]
	if visited[x] != i:
		continue
	a = x
	mi = l[x]
	while s[x] != a:
		x = s[x]
		mi = min(mi, l[x])
	ans += mi
print(ans)


def dfs(node, edges, costs, visited):
	cycle = False
	visited1 = set()
	while True:
		if node in visited:
			for i in visited1:
				visited.add(i)
			return 0
		if not edges[node]:
			visited1.add(node)
			break
		if node not in visited1:
			visited1.add(node)
			node = edges[node][0]
		else:
			cycle = True
			break
	if cycle:
		x = edges[node][0]
		min_cost = costs[x - 1]
		while x != node:
			x = edges[x][0]
			min_cost = min(min_cost, costs[x - 1])
		cost = min_cost
	else:
		cost = costs[node - 1]
	for i in visited1:
		visited.add(i)
	return cost

def solve(zero, edges, costs):
	n = len(costs)
	visited = set()
	cost = 0
	for i in range(1, n + 1):
		if i not in visited:
			cost += dfs(i, edges, costs, visited)
	print(cost)

def main():
	n = int(input())
	costs = list(map(int, input().split()))
	mouse = list(map(int, input().split()))
	edges = {}
	for i in range(1, n + 1):
		edges[i] = []
	indegree = [0] * (n + 1)
	for i in range(1, n + 1):
		if i != mouse[i - 1]:
			edges[i].append(mouse[i - 1])
			indegree[mouse[i - 1]] += 1
	zero = []
	for i in range(1, n + 1):
		if indegree[i] == 0:
			zero.append(i)
	solve(zero, edges, costs)
main()


import sys
readline = sys.stdin.readline
N = int(readline())
C = list(map(int, readline().split()))
A = list(map(lambda x: int(x) - 1, readline().split()))
inf = 10 ** 9
used = set()
ans = 0
for i in range(N):
	if i in used:
		continue
	seen = set()
	stack = [i]
	cnt = 0
	st = None
	while stack:
		vn = stack.pop()
		vf = A[vn]
		if vf in used:
			break
		if vf in seen:
			st = vf
			break
		seen.add(vf)
		stack.append(vf)
	if st is not None:
		vn = st
		cnt = C[vn]
		vf = A[vn]
		vn = A[vn]
		while vn != st:
			cnt = min(cnt, C[vn])
			vn = A[vn]
	used |= seen
	ans += cnt
print(ans)


n = int(input())
c = [0] + [int(j) for j in input().split()]
a = [0] + [int(j) for j in input().split()]
vis = [0] * (n + 1)
ans = 0
for i in range(1, n + 1):
	x = i
	while vis[x] == 0:
		vis[x] = i
		x = a[x]
	if vis[x] != i:
		continue
	v = x
	mn = c[x]
	while a[x] != v:
		x = a[x]
		mn = min(mn, c[x])
	ans += mn
print(ans)


n = int(input())
c = [int(x) for x in input().split()]
c.insert(0, 0)
a = [int(x) for x in input().split()]
a.insert(0, 0)
done = [0] * (n + 1)
sol = 0
c_i = 0
for i in range(1, n + 1):
	c_i += 2
	cost = 0
	if done[i] != 0:
		continue
	while done[i] == 0:
		done[i] = c_i
		i = a[i]
	if done[i] == c_i:
		cost = c[i]
		while done[i] == c_i:
			done[i] += 1
			i = a[i]
			if c[i] < cost:
				cost = c[i]
	sol += cost
print(sol)


n = int(input())
cost = [0] + [int(item) for item in input().split()]
route = [0] + [int(r) for r in input().split()]
visited = [0] + [False for i in range(n)]
ans = 0
for i in range(1, n + 1):
	if visited[i] == True:
		continue
	circle = []
	node = i
	while visited[node] == False:
		visited[node] = True
		circle.append(node)
		node = route[node]
	temp = circle.copy()
	for vertex in temp:
		if vertex == node:
			break
		tmp = circle.pop(0)
	if circle != []:
		ans += min([cost[item] for item in circle])
print(ans)


import sys
from array import array

def readline():
	return sys.stdin.buffer.readline().decode('utf-8')
n = int(readline())
cost = (0,) + tuple(map(int, readline().split()))
a = (0,) + tuple(map(int, readline().split()))
deg = [0] * (n + 1)
visited = [0] * (n + 1)
for d in a[1:]:
	deg[d] += 1
for i in range(1, n + 1):
	if visited[i] or deg[i]:
		continue
	v = i
	while deg[v] == 0:
		visited[v] = 1
		deg[a[v]] -= 1
		v = a[v]
ans = 0
for i in range(1, n + 1):
	if visited[i]:
		continue
	visited[i] = 1
	(v, mincost) = (a[i], cost[i])
	while v != i:
		visited[v] = 1
		if mincost > cost[v]:
			mincost = cost[v]
		v = a[v]
	ans += mincost
print(ans)


n = int(input())
c = [0] + list(map(int, input().split()))
a = [0] + list(map(int, input().split()))
g = [0] * (n + 1)
answer = 0
for i in range(1, n + 1):
	node = i
	while g[node] == 0:
		g[node] = i
		node = a[node]
	if g[node] != i:
		continue
	current = node
	min_cost = c[node]
	while a[node] != current:
		node = a[node]
		min_cost = min(min_cost, c[node])
	answer += min_cost
print(answer)


def count(n, c, a):
	vis = [0] * (n + 1)
	z = []
	p = []
	for i in range(1, n + 1):
		x = i
		while vis[x] == 0:
			vis[x] = i
			x = a[x - 1]
		if vis[x] == i:
			p.append(x)
	return p

def opium(n, c, a):
	sum = 0
	p = list(set(count(n, c, a)))
	for x in p:
		v = x
		cd = c[x - 1]
		while v != a[x - 1]:
			x = a[x - 1]
			cd = min(cd, c[x - 1])
		sum = sum + cd
	return sum

def main():
	n = int(input())
	c = [int(i) for i in input().split()]
	a = [int(i) for i in input().split()]
	return opium(n, c, a)
print(main())


n = int(input())
c = list(map(int, input().split()))
a = list(map(int, input().split()))
ans = 0
v = [False for i in range(n)]
for i in range(n):
	if v[i]:
		continue
	p = set()
	pl = []
	s = set([i])
	t = True
	while s and t:
		x = s.pop()
		v[x] = True
		p.add(x)
		pl.append(x)
		nex = a[x] - 1
		s.add(nex)
		if nex in p:
			j = pl.index(nex)
			za = s.pop()
		elif v[nex]:
			t = False
			za = s.pop()
	if not t:
		continue
	an = float('INF')
	for k in range(j, len(pl)):
		an = min(c[pl[k]], an)
	ans += an
print(ans)


n = int(input())
c = list(map(int, input().split()))
a = list(map(int, input().split()))
v = [0] * (n + 1)
y = [0] * (n + 1)
f = [0] * (n + 1)
j = 1
p = 0
while j <= n:
	if v[j] == 0:
		s = [j]
		while s:
			m = s.pop()
			v[m] = 1
			r = a[m - 1]
			if f[r] == 1:
				break
			if v[r] == 0:
				s.append(r)
		if f[r] != 1:
			q = r
			s = [j]
			d = 10 ** 10
			while s:
				m = s.pop()
				if m == q:
					d = min(d, c[m - 1])
					q = a[m - 1]
				y[m] = 1
				f[m] = 1
				r = a[m - 1]
				if y[r] == 0:
					s.append(r)
			p += d
		else:
			s = [j]
			while s:
				m = s.pop()
				y[m] = 1
				if f[m] == 1:
					break
				else:
					f[m] = 1
				r = a[m - 1]
				if y[r] == 0:
					s.append(r)
	else:
		pass
	j += 1
print(p)


import sys
rd = lambda : sys.stdin.readline().rstrip()
n = int(rd())
c = list(map(int, rd().split()))
a = list([int(x) - 1 for x in rd().split()])
visited = [-1] * n
res = 0
for i in range(n):
	trace = []
	t = i
	mn = 1000000000.0
	while visited[t] == -1:
		visited[t] = i
		trace.append(t)
		t = a[t]
	if visited[t] != i:
		continue
	while len(trace) > 0:
		v = trace.pop()
		mn = min(mn, c[v])
		if t == v:
			break
	res += mn
print(res)


import sys
import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
n = int(input())
C = list(map(int, input().split()))
A = list(map(int, input().split()))
A = [a - 1 for a in A]
visit = [False] * n
loops = []
for i in range(n):
	if not visit[i]:
		s = [i]
		temp = set()
		temp.add(i)
		flag = False
		while s:
			v = s.pop()
			if visit[A[v]]:
				break
			if A[v] in temp:
				flag = True
				p = A[v]
				break
			else:
				s.append(A[v])
				temp.add(A[v])
		if flag:
			loop = [p]
			nv = A[p]
			cnt = 0
			while nv != p:
				loop.append(nv)
				nv = A[nv]
			loops.append(loop)
		for v in temp:
			visit[v] = True
ans = 0
for l in loops:
	m = 10 ** 18
	for i in l:
		m = min(m, C[i])
	ans += m
print(ans)


import sys, os, io
from sys import stdin
import math
from collections import defaultdict
from heapq import heappush, heappop, heapify
from bisect import bisect_left, bisect_right
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')
alphabets = list('abcdefghijklmnopqrstuvwxyz')
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 ncr(n, r, p):
	num = den = 1
	for i in range(r):
		num = num * (n - i) % p
		den = den * (i + 1) % p
	return num * pow(den, p - 2, p) % p

def primeFactors(n):
	l = []
	while n % 2 == 0:
		l.append(2)
		n = n / 2
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		while n % i == 0:
			l.append(int(i))
			n = n / i
	if n > 2:
		l.append(n)
	return list(set(l))

def power(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

def sieveForSmallestPrimeFactor():
	MAXN = 100001
	spf = [0 for i in range(MAXN)]
	spf[1] = 1
	for i in range(2, MAXN):
		spf[i] = i
	for i in range(4, MAXN, 2):
		spf[i] = 2
	for i in range(3, math.ceil(math.sqrt(MAXN))):
		if spf[i] == i:
			for j in range(i * i, MAXN, i):
				if spf[j] == j:
					spf[j] = i
	return spf

def getPrimeFactorizationLOGN(x):
	spf = sieveForSmallestPrimeFactor()
	ret = list()
	while x != 1:
		ret.append(spf[x])
		x = x // spf[x]
	return ret

def SieveOfEratosthenes(n):
	prime = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	return prime

def si():
	return input()

def divideCeil(n, x):
	if n % x == 0:
		return n // x
	return n // x + 1

def ii():
	return int(input())

def li():
	return list(map(int, input().split()))
if os.path.exists('input.txt'):
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
	input = lambda : sys.stdin.readline().rstrip('\r\n')

def solve():
	n = ii()
	c = [0] + li()
	a = [0] + li()
	vis = [False] * (n + 1)
	ans = 0
	d = defaultdict(lambda : 0)
	cycleno = 0
	for i in range(1, n + 1):
		if vis[i] == False:
			cur = i
			first = i
			while vis[cur] == False:
				d[cur] = cycleno
				vis[cur] = True
				cur = a[cur]
			if d[cur] == cycleno:
				min_ = c[cur]
				first = cur
				cur = a[cur]
				while first != cur:
					min_ = min(c[cur], min_)
					cur = a[cur]
				ans += min_
			cycleno += 1
	print(ans)
t = 1
for _ in range(t):
	solve()


input()
c = list(map(int, input().split()))
a = list(map(int, input().split()))
u = [0] * len(a)
ans = 0
for i in range(len(a)):
	if u[i] != 0:
		continue
	idx = i
	while u[idx] == 0:
		u[idx] = 1
		idx = a[idx] - 1
	if u[idx] == 2:
		idx = i
		while u[idx] == 1:
			u[idx] = 2
			idx = a[idx] - 1
		continue
	start = idx
	mn = c[idx]
	u[idx] = 2
	while a[idx] - 1 != start:
		idx = a[idx] - 1
		mn = min(mn, c[idx])
		u[idx] = 2
	idx = i
	while u[idx] == 1:
		u[idx] = 2
		idx = a[idx] - 1
	ans += mn
print(ans)


N = int(input())
C = [0] + [int(x) for x in input().split()]
A = [0] + [int(x) for x in input().split()]
ans = 0
vis = [False] * (N + 1)
for i in range(1, N + 1):
	if vis[i]:
		continue
	circle = []
	u = i
	while not vis[u]:
		circle.append(u)
		vis[u] = True
		u = A[u]
	if u in circle:
		ans += min([C[j] for j in circle[circle.index(u):]])
print(ans)


def kormin(kezd, K, a, c):
	i = kezd
	hal = [kezd]
	K[kezd] = 1
	elert = 1
	while K[a[i]] == 0 and korben[a[i]] == 0:
		K[a[i]] = 1
		hal.append(a[i])
		elert = elert + 1
		i = a[i]
	minkor = 0
	if korben[a[i]] == 0 and a[i] in hal:
		vege = i
		minkor = c[i]
		korben[i] = 1
		while a[i] != vege:
			korben[a[i]] = 1
			if c[a[i]] < minkor:
				minkor = c[a[i]]
			i = a[i]
	return [elert, minkor]
n = int(input())
c = []
t = input().split()
for i in range(n):
	c.append(int(t[i]))
a = []
t = input().split()
for i in range(n):
	a.append(int(t[i]) - 1)
korben = []
K = []
for i in range(n):
	K.append(0)
	korben.append(0)
feldolg = 0
osszeg = 0
kezd = 0
while feldolg < n:
	while K[kezd] == 1:
		kezd = kezd + 1
	x = kormin(kezd, K, a, c)
	feldolg = feldolg + x[0]
	osszeg = osszeg + x[1]
print(osszeg)


n = int(input())
c = list(map(int, input().split()))
a = list(map(lambda x: int(x) - 1, input().split()))
deg_in = [0 for _ in range(n)]
d_in_to_v_set = {i: set() for i in range(n + 1)}
for ai in a:
	deg_in[ai] += 1
for i in range(n):
	d_in_to_v_set[deg_in[i]].add(i)
while d_in_to_v_set[0] != set():
	l = list(d_in_to_v_set[0])
	for u in l:
		d_in_to_v_set[deg_in[a[u]]].remove(a[u])
		d_in_to_v_set[deg_in[a[u]] - 1].add(a[u])
		d_in_to_v_set[0].remove(u)
		deg_in[a[u]] -= 1
p = [0 for _ in range(n)]
for v in d_in_to_v_set[1]:
	p[v] = 1
(ans, cur) = (0, 10 ** 5)
for i in range(n):
	s = i
	cur = 10 ** 5
	while p[s] != 0:
		cur = min(cur, c[s])
		p[s] = 0
		s = a[s]
	ans += cur if cur < 10 ** 5 else 0
print(ans)


def main():
	n = int(input())
	c = [int(i) for i in input().split()]
	a = [int(i) for i in input().split()]
	vis = [0] * (n + 1)
	sum = 0
	for i in range(1, n + 1):
		x = i
		while vis[x] == 0:
			vis[x] = i
			x = a[x - 1]
		if vis[x] != i:
			continue
		p = x
		cos = c[x - 1]
		while p != a[x - 1]:
			x = a[x - 1]
			cos = min(c[x - 1], cos)
		sum = sum + cos
	return sum
print(main())


n = int(input())
c = list(map(int, input().strip().split()))
a = list(map(int, input().strip().split()))
resd = {}
res = 0
tmpd = {}
for i in range(n):
	cur = i + 1
	d = {}
	group = []
	flag = False
	while cur not in d:
		if cur in tmpd:
			flag = True
			break
		d[cur] = 1
		tmpd[cur] = 1
		group.append(cur)
		cur = a[cur - 1]
	if flag:
		continue
	mmin = float('inf')
	ind = float('inf')
	flag = False
	for item in group:
		if item == cur:
			flag = True
		if flag:
			mmin = min(c[item - 1], mmin)
			ind = min(ind, item)
	if ind in resd:
		continue
	else:
		resd[ind] = 1
		res += mmin
print(res)


import sys
input = sys.stdin.readline

class Unionfind:

	def __init__(self, n):
		self.par = [-1] * n
		self.rank = [1] * n

	def root(self, x):
		p = x
		while not self.par[p] < 0:
			p = self.par[p]
		while x != p:
			tmp = x
			x = self.par[x]
			self.par[tmp] = p
		return p

	def unite(self, x, y):
		(rx, ry) = (self.root(x), self.root(y))
		if rx == ry:
			return False
		if self.rank[rx] < self.rank[ry]:
			(rx, ry) = (ry, rx)
		self.par[rx] += self.par[ry]
		self.par[ry] = rx
		if self.rank[rx] == self.rank[ry]:
			self.rank[rx] += 1

	def is_same(self, x, y):
		return self.root(x) == self.root(y)

	def count(self, x):
		return -self.par[self.root(x)]
n = int(input())
c = list(map(int, input().split()))
uf = Unionfind(n)
a = list(map(int, input().split()))
for i in range(n):
	uf.unite(i, a[i] - 1)
roots = set((uf.root(i) for i in range(n)))
ans = 0
for r in roots:
	cur = r
	s = {r}
	while True:
		nex = a[cur] - 1
		if nex in s:
			sta = nex
			break
		s.add(nex)
		cur = nex
	add = c[sta]
	cur = sta
	while True:
		nex = a[cur] - 1
		if nex == sta:
			break
		add = min(add, c[nex])
		cur = nex
	ans += add
print(ans)


def main():
	(n, r) = (int(input()) + 1, 0)
	cc = [0, *list(map(int, input().split()))]
	aa = [0, *list(map(int, input().split()))]
	avail = [True] * n
	for (i, a) in enumerate(avail):
		if a:
			j = i
			while avail[j]:
				avail[j] = False
				j = aa[j]
			(c, j) = (cc[j], aa[j])
			if c:
				while cc[j]:
					if c > cc[j]:
						c = cc[j]
					cc[j] = 0
					j = aa[j]
				r += c
			while cc[i]:
				cc[i] = 0
				i = aa[i]
	print(r)

def __starting_point():
	main()
__starting_point()


import collections

def do():
	n = int(input())
	costs = [int(c) for c in input().split(' ')]
	next = [int(c) - 1 for c in input().split(' ')]
	ind = [0] * n
	for (i, c) in enumerate(next):
		if i != c:
			ind[c] += 1
	seen = [0] * n
	res_seen = [0] * n
	res = 0

	def get(entry):
		m = costs[entry]
		p = entry
		while True:
			if res_seen[p]:
				return 0
			res_seen[p] = 1
			m = min(m, costs[p])
			p = next[p]
			if p == entry:
				break
		return m

	def dfs(i):
		stack = [i]
		seen[i] = 1
		while stack:
			cur = stack.pop()
			nei = next[cur]
			if seen[nei]:
				return get(nei)
			seen[nei] = 1
			stack.append(nei)
		return 0
	for i in range(n):
		if ind[i] == 0:
			res += dfs(i)
	for i in range(n):
		if seen[i] == 0:
			res += dfs(i)
	return res
print(do())


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 factorial
from collections import Counter, defaultdict
from heapq import heapify, heappop, heappush

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

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

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

def comb(n, m):
	return factorial(n) / (factorial(m) * factorial(n - m)) if n >= m else 0

def perm(n, m):
	return factorial(n) // factorial(n - m) if n >= m else 0

def mdis(x1, y1, x2, y2):
	return abs(x1 - x2) + abs(y1 - y2)

def ctd(chr):
	return ord(chr) - ord('a')
mod = 998244353
INF = float('inf')

def main():
	n = N()
	arrc = RLL()
	arra = RLL()
	res = 0
	vis = [0] * n
	for i in range(n):
		if vis[i] == 1:
			continue
		rec = []
		ti = i
		while vis[ti] == 0:
			vis[ti] = 1
			rec.append(ti)
			ti = arra[ti] - 1
		for j in range(len(rec)):
			if rec[j] == ti:
				res += min([arrc[k] for k in rec[j:]])
	print(res)
main()


n = input()
a = list(map(int, input().split()))
a_next = list(map(int, input().split()))
for i in range(len(a_next)):
	a_next[i] -= 1
cycles = []
check = [0] * len(a)

def dfs(v):
	path = []
	s = []
	check[v] = 1
	path.append(v)
	s.append(v)
	while s:
		next_v = a_next[s[-1]]
		if check[next_v] == 0:
			check[next_v] = 1
			path.append(next_v)
			s.append(next_v)
		else:
			if check[next_v] == 1:
				cycle = []
				while path[-1] != next_v:
					cycle.append(path.pop())
				cycle.append(next_v)
				cycles.append(cycle)
			while s:
				check[s.pop()] = 2
for i in range(len(a)):
	if check[i] == 0:
		dfs(i)
ans = 0
for cycle in cycles:
	min_cost = a[cycle[0]]
	for v in cycle:
		if a[v] < min_cost:
			min_cost = a[v]
	ans += min_cost
print(ans)


n = int(input())
carr = list(map(int, input().split()))
marr = list(map(int, input().split()))
v = set()
cs = []
for x in marr:
	if x not in v:
		new = True
		cv = set()
		cv.add(x)
		while marr[x - 1] not in cv:
			x = marr[x - 1]
			cv.add(x)
			if x in v:
				new = False
				break
		v |= cv
		if new:
			cs.append((x, marr[x - 1]))
c = 0
for (x, y) in cs:
	p = set()
	p.add(x)
	p.add(y)
	while marr[y - 1] not in p:
		y = marr[y - 1]
		p.add(y)
	c += min(map(lambda o: carr[o - 1], p))
print(c)


n = int(input())
costs = [int(x) for x in input().split()]
edges = [int(x) for x in input().split()]
colors = []
graph = {}
c = {}
for i in range(1, n + 1):
	graph[i] = []
for i in range(0, len(edges)):
	graph[i + 1].append(edges[i])
colors = [0] * (n + 5)
result = 0

def analize(v):
	cheaper = 10000000000
	begin = False
	for u in c.keys():
		if c[u] == v:
			if costs[v - 1] < cheaper:
				cheaper = costs[v - 1]
			begin = True
		if begin and costs[u - 1] < cheaper:
			cheaper = costs[u - 1]
	if begin:
		return cheaper
	return 0

def dfs(u):
	while u:
		colors[u] = 1
		b = False
		for v in graph[u]:
			if colors[v] == 1:
				if u == v:
					c[v] = u
				u = v
				return v
				b = True
				break
			if colors[v] == 0:
				c[v] = u
				u = v
				b = True
				break
		if not b:
			colors[u] = 2
			if len(c) > 0:
				if u in c.keys():
					del c[u]
			u = 0
	return u
for u in graph.keys():
	if colors[u] == 0:
		c = {}
		v = dfs(u)
		result += analize(v)
print(result)


n = int(input())
C = [int(s) for s in input().split(' ')]
A = [int(s) - 1 for s in input().split(' ')]
al = [False for i in range(0, n)]
ans = 0
for v in range(0, n):
	if al[v]:
		continue
	sequence = []
	while not al[v]:
		sequence.append(v)
		al[v] = True
		v = A[v]
	if v in sequence:
		tek = C[v]
		for j in sequence[sequence.index(v) + 1:]:
			tek = min(C[j], tek)
		ans += tek
print(ans)


n = int(input())
cst = list(map(int, input().split()))
route = list(map(int, input().split()))
visited = [0] * n
cost = 0
for i in range(n):
	if visited[i] == 0:
		mini = 99999999
		j = i
		while visited[j] == 0:
			visited[j] = i + 1
			j = route[j] - 1
			if visited[j] == i + 1:
				mini = cst[j]
				k = route[j] - 1
				while k != j:
					if cst[k] < mini:
						mini = cst[k]
					k = route[k] - 1
		if mini != 99999999:
			cost += mini
print(cost)


n = int(input())
burles = list(map(int, input().split()))
directions = list(map(int, input().split()))
burles.insert(0, 0)
directions.insert(0, 0)
v = [0] * (n + 1)
g = [0] * (n + 1)

def passa(pos):
	global current_group
	global v
	global g
	global soma_total
	pilha = [-1]
	avanco = True
	grupo = 0
	esta_no_ciclo = False
	menor_local = 0
	while pilha:
		if avanco:
			if v[pos] == 1:
				v[pos] = 2
				if g[pos] == 0:
					g[pos] = current_group
					current_group += 1
				grupo = g[pos]
				avanco = False
				esta_no_ciclo = True
				menor_local = burles[pos]
			elif v[pos] == 2 or v[pos] == 3:
				grupo = g[pos]
				avanco = False
				esta_no_ciclo = False
				grupo = g[pos]
			else:
				v[pos] = 1
				pilha.append(pos)
				pos = directions[pos]
		else:
			pos = pilha.pop(len(pilha) - 1)
			if pos < 0:
				continue
			g[pos] = grupo
			if v[pos] == 2 and esta_no_ciclo:
				soma_total += menor_local
				esta_no_ciclo = False
			elif v[pos] == 1 and esta_no_ciclo:
				v[pos] = 2
				menor_local = min(menor_local, burles[pos])
			if v[pos] == 1 and (not esta_no_ciclo):
				v[pos] = 3
current_group = 1
soma_total = 0
for i in range(1, n + 1):
	if v[i] == 0:
		passa(i)
print(soma_total)


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 math
import bisect
mod = 998244353
from collections import Counter
import bisect
from heapq import *
from collections import defaultdict
n = int(input())
cost = [0] + list(map(int, input().split()))
arr = [0] + list(map(int, input().split()))
v = [0] * (n + 2)
ans = 0
for i in range(1, n + 1):
	if v[i]:
		continue
	u = i
	circle = []
	while v[u] == 0:
		circle.append(u)
		v[u] = 1
		u = arr[u]
	f = 0
	if u in circle:
		f = 1
		mi = min((cost[j] for j in circle[circle.index(u):]))
	if f == 1:
		ans += mi
print(ans)


import sys, os, io
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
n = int(input())
c = [int(i) for i in input().split()]
a = [int(i) - 1 for i in input().split()]
vis = [-1] * n
ans = 0
for i in range(n):
	ind = i
	while vis[ind] == -1:
		vis[ind] = i
		ind = a[ind]
	if vis[ind] == i:
		start = ind
		ind = a[ind]
		cost = c[start]
		while ind != start:
			cost = min(cost, c[ind])
			ind = a[ind]
		ans += cost
print(ans)


n = int(input())
c = list(map(int, input().split()))
a = list([int(x) - 1 for x in input().split()])
b = [None] * n
processed = [False for i in range(n)]
for i in range(n):
	if not b[a[i]]:
		b[a[i]] = {i}
	else:
		b[a[i]].add(i)
rings = []

def processed_ring(ring):
	copy_ring = ring.copy()
	while copy_ring:
		new_ring = set()
		for el in copy_ring:
			processed[el] = True
			if b[el]:
				new_ring |= b[el]
		copy_ring = new_ring - copy_ring
for i in range(n):
	if processed[i]:
		continue
	ring = set()
	position = set()
	next_pos = i
	while next_pos not in position:
		position.add(next_pos)
		next_pos = a[next_pos]
	while next_pos not in ring:
		ring.add(next_pos)
		next_pos = a[next_pos]
	processed_ring(ring)
	rings.append(ring)
res = sum((min((c[i] for i in ring)) for ring in rings))
print(res)