Problem:
 Score : 400 points    Problem Statement Takahashi will play a game using a piece on an array of squares numbered 1, 2, \cdots, N . Square i has an integer C_i written on it. Also, he is given a permutation of 1, 2, \cdots, N : P_1, P_2, \cdots, P_N .  Now, he will choose one square and place the piece on that square. Then, he will make the following move some number of times between 1 and K (inclusive):   In one move, if the piece is now on Square i  (1 \leq i \leq N) , move it to Square P_i . Here, his score increases by C_{P_i} .   Help him by finding the maximum possible score at the end of the game. (The score is 0 at the beginning of the game.)      Constraints  2 \leq N \leq 5000  1 \leq K \leq 10^9  1 \leq P_i \leq N  P_i \neq i  P_1, P_2, \cdots, P_N are all different.  -10^9 \leq C_i \leq 10^9  All values in input are integers.         Input Input is given from Standard Input in the following format:  N  K  P_1  P_2  \cdots  P_N  C_1  C_2  \cdots  C_N       Output Print the maximum possible score at the end of the game.        Sample Input 1 5 2
2 4 5 1 3
3 4 -10 -8 8      Sample Output 1 8  When we start at some square of our choice and make at most two moves, we have the following options:   If we start at Square 1 , making one move sends the piece to Square 2 , after which the score is 4 . Making another move sends the piece to Square 4 , after which the score is 4 + (-8) = -4 .  If we start at Square 2 , making one move sends the piece to Square 4 , after which the score is -8 . Making another move sends the piece to Square 1 , after which the score is -8 + 3 = -5 .  If we start at Square 3 , making one move sends the piece to Square 5 , after which the score is 8 . Making another move sends the piece to Square 3 , after which the score is 8 + (-10) = -2 .  If we start at Square 4 , making one move sends the piece to Square 1 , after which the score is 3 . Making another move sends the piece to Square 2 , after which the score is 3 + 4 = 7 .  If we start at Square 5 , making one move sends the piece to Square 3 , after which the score is -10 . Making another move sends the piece to Square 5 , after which the score is -10 + 8 = -2 .   The maximum score achieved is 8 .       Sample Input 2 2 3
2 1
10 -7      Sample Output 2 13       Sample Input 3 3 3
3 1 2
-1000 -2000 -3000      Sample Output 3 -1000  We have to make at least one move.       Sample Input 4 10 58
9 1 6 7 8 4 3 2 10 5
695279662 988782657 -119067776 382975538 -151885171 -177220596 -169777795 37619092 389386780 980092719      Sample Output 4 29507023469  The absolute value of the answer may be enormous.

Solution (Python):
import sys

import numpy as np


def main(n,k,p,c):
    ans = -10**9
    for i in range(n):
        x = i
        t = k
        count = 0
        l = True
        sub = 0
        ln = 0
        while True:
            x = p[x] - 1
            if l:
                count += c[x]
                ln += 1
                if x == i:
                    if t > ln:
                        if count > 0:
                            sub += (t // ln - 1) * count
                            t %= ln
                            t += ln
                        else:
                            t = 0
                    l = False
            sub += c[x]
            t -= 1
            ans = max(sub, ans)
            if t < 1:
                break
    return ans



if sys.argv[-1]=='ONLINE_JUDGE' or sys.argv[-1]=='main.py':
  from numba.pycc import CC
  cc=CC('my_module')
  cc.export('main','i8(i8,i8,i8[:],i8[:])')(main)
  cc.compile()
  exit()
from my_module import main

(n, k), p, c = [np.int_(i.split()) for i in open(0)]
print(main(n,k,p,c))

Solution (Python):
from collections import defaultdict
from collections import deque
from collections import Counter
import math

def readInt():
	return int(input())
def readInts():
	return list(map(int, input().split()))
def readChar():
	return input()
def readChars():
	return input().split()

n,k = readInts()
p = [0]+readInts()
c = [0]+readInts()

ans = -1*float("inf")
for i in range(1,n+1):
	j = p[i]
	t = [0]
	al = set()
	while j not in al:
		t.append(t[-1]+c[j])
		al.add(j)
		j = p[j]
	if t[-1]<=0:
		ans = max(ans, max(t[1:k+1]))
	else:
		kuri =(k-1)//(len(t)-1)
		s = kuri*t[-1]
		re = k -kuri*(len(t)-1)
		ans = max(ans, max(s,s+max(t[:re+1])))

print(ans)

Solution (Python):
n,k=[int(x) for x in input().split()]
p=[int(x)-1 for x in input().split()]
c=[int(x) for x in input().split()]

ans=max(c)
if ans<0:
    print(ans)
    exit()

for i in range(n):
    
    nxt=i
    lp=[]
    while 1:
        nxt=p[nxt]
        lp.append(nxt)
        if nxt==i:
            break
    lpc=sum(c[x] for x in lp)
    nxt=i
    lpl=len(lp)
    wks=0
    for j in range(lpl):
        nxt=p[nxt]
        wks+=c[nxt]
        ans=max(ans,(k-j-1)//lpl*max(0,lpc)+wks)
        if j==k-1:
            break
print(ans)

Solution (Python):
N, K = map(int, input().split())
P = list(map(int, input().split()))
C = list(map(int, input().split()))
P = [i - 1 for i in P]

ans = -10**18
for si in range(N):
    x = si
    s = []
    total = 0
    while True:
        x = P[x]
        s.append(C[x])
        total += C[x]
        if x == si: break
    l = len(s)
    t = 0
    for i in range(l):
        t += s[i]
        if i + 1 > K: break
        now = t
        if total > 0:
            e = (K - (i + 1)) // l
            now += total * e
        ans = max(ans, now)
print(ans)

Solution (Python):
n, k = map(int, input().split())
p = [0] + list(map(int, input().split()))
c = [0] + list(map(int, input().split()))

ans = - 10 ** 18
for i in range(1, n+1):
    base = i
    nxt = p[i]
    cnt = 0
    score = 0
    while True:
        cnt += 1
        if cnt > k:
            break
        score += c[nxt]
        ans = max(ans, score)
        
        if nxt == base:
            break
        nxt = p[nxt]
    if cnt >= k:
        continue
    extra = k - cnt
    score_tmp = score
    nxt = p[nxt]
    nxt_tmp = nxt
    for j in range(min(extra, cnt)):
        score += c[nxt]
        ans = max(ans, score)
        
        nxt = p[nxt]
    
    score = score_tmp
    nxt = nxt_tmp
    a = extra // cnt
    if extra % cnt == 0:
        a -= 1
    score += score * max(a, 0)
    ans = max(ans, score)
    for j in range(extra - a * cnt):
        score += c[nxt]
        ans = max(ans, score)
        
        nxt = p[nxt]

print(ans)

Solution (Python):





def main(n,k,p,c):
    ans = -10**9
    for i in range(n):
        x = i
        t = k
        count = 0
        l = True
        sub = 0
        ln = 0
        while True:
            x = p[x] - 1
            if l:
                count += c[x]
                ln += 1
                if x == i:
                    if t > ln:
                        if count > 0:
                            sub += (t // ln - 1) * count
                            t %= ln
                            t += ln
                        else:
                            t = 0
                    l = False
            sub += c[x]
            t -= 1
            ans = max(sub, ans)
            if t < 1:
                break
    return ans











(n, k), p, c = [[*map(int,i.split())] for i in open(0)]
print(main(n,k,p,c))

Solution (Python):
import sys

import numpy as np


def main(n,k,p,c):
    ans = -10**9
    for i in range(n):
        x = i
        t = k
        count = 0
        l = True
        sub = 0
        ln = 0
        while True:
            x = p[x] - 1
            if l:
                count += c[x]
                ln += 1
                if x == i:
                    if t > ln:
                        if count > 0:
                            sub += (t // ln - 1) * count
                            t %= ln
                            t += ln
                        else:
                            t = 0
                    l = False
            sub += c[x]
            t -= 1
            ans = max(sub, ans)
            if t < 1:
                break
    return ans



if sys.argv[-1]=='ONLINE_JUDGE':
  from numba.pycc import CC
  cc=CC('my_module')
  cc.export('main','i8(i8,i8,i8[:],i8[:])')(main)
  cc.compile()
  exit()
from my_module import main

(n, k), p, c = [np.int_(i.split()) for i in open(0)]
print(main(n,k,p,c))

Solution (Python):
n,k = map(int,input().split())
p = list(map(int,input().split()))
c = list(map(int,input().split()))
p = [pi-1 for pi in p]

ans = -1e18
for i in range(n):
  cur = p[i]
  loop = [c[cur]]
  cnt = 1
  ans = max(ans,c[cur])
  while cur != i and cnt<k:
    cur = p[cur]
    tmp = loop[-1]+c[cur]
    loop.append(tmp)
    ans = max(ans,tmp)
    cnt += 1
  
  if cnt==k or loop[-1]<=0:continue
  a = k//len(loop) * loop[-1]
  b = (k//len(loop)-1) * loop[-1]
  ans = max(ans,a,b)
  for _ in range(k%len(loop)):
    a += c[cur]
    ans = max(ans,a)
    cur = p[cur]
  cur = i
  for _ in range(len(loop)):
    b += c[cur]
    ans = max(ans,b)
    cur = p[cur]
print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(10**7)

readline = sys.stdin.buffer.readline
def readstr():return readline().rstrip().decode()
def readstrs():return list(readline().decode().split())
def readint():return int(readline())
def readints():return list(map(int,readline().split()))
def printrows(x):print('\n'.join(map(str,x)))
def printline(x):print(' '.join(map(str,x)))

from itertools import accumulate

def circle_sum_max(circle,num):
    n = len(circle)
    s = sum(circle)
    if num == 0:
        ans = 0
    elif num == 1:
        ans = max(circle)
    else:
        ac = list(accumulate([0]+circle))

        l = 0
        r = 1
        ans = ac[r]-ac[l]
        i = 0
        while r!=n or i%2==1:
            if i%2==0:
                r = ac[r+1:l+num+1].index(max(ac[r+1:l+num+1])) + r+1
            else:
                l = ac[l+1:r].index(min(ac[l+1:r])) + l+1
            i+=1
            ans = max(ans,ac[r]-ac[l])
 
        num = n-num
        l = 0
        r = num
        i = 0
        ans = max(ans,s-ac[r]+ac[l])
        while r!=n or i%2==1:
            if i%2==0:
                r = ac[r+1:l+n].index(min(ac[r+1:l+n])) + r+1
            else:
                l = ac[l+1:r-num+1].index(max(ac[l+1:r-num+1])) + l+1
            i+=1
            ans = max(ans,s-ac[r]+ac[l])
    return ans
 

n,k = readints()
p = [x-1 for x in readints()]
c = readints()

circles = []
used = [0]*n

for i in range(n):
    if not used[i]:
        circles.append([c[i]])
        used[i] = 1
        j = p[i]
        while not used[j]:
            circles[-1].append(c[j])
            used[j] = 1
            j = p[j]

score = -10**20

for cir in circles:
    m = len(cir)
    a = sum(cir)
    if k>m:
        if a>0:
            score = max(score, (k//m)*a + circle_sum_max(cir,k%m), (k//m-1)*a + circle_sum_max(cir,m))
        else:
            score = max(score,circle_sum_max(cir,m))
    else:
        score = max(score,circle_sum_max(cir,k))

print(score)

Solution (Python):
(n, k), p, c = [[*map(int, i.split())] for i in open(0)]
 
def solve(x, t):
    visit = [0] * n
    visit[x] = 1
    loop = [0] * n
    count = 0
    ans = c[p[x] - 1]
    l = True
    sub = 0
    while True:
        x = p[x] - 1
        if l:
            if visit[x]:
                if loop[x]:
                    ln = sum(loop)
                    if t > ln:
                        sub += (t//ln -1)*count*(count>0)
                        t %= ln
                        t += ln
                    l = False
                count += c[x]
                loop[x] = 1
            visit[x] = 1
        sub += c[x]
        t -= 1
        ans = max(sub, ans)
        if t < 1:
            return ans
 
 
print(max(solve(i, k) for i in range(n)))

Solution (Python):
n, k = [int(z) for z in input().strip().split()]
p = [int(z) - 1 for z in input().strip().split()]
c = [int(z) for z in input().strip().split()]
 
visited = [False for _ in range(n)]
cycle = []
for start in range(n):
    if visited[start]:
        continue
    now = start
    route = []
    while not visited[now]:
        visited[now] = True
        route.append(now)
        now = p[now]
    cycle.append(route)
 
min_c = min(c)
max_value = min_c
for route in cycle:
    full_value = sum([c[i] for i in route])
    double_route = route + route
    v = [c[i] for i in double_route]
    max_sum_step = []
    for step in range(1, len(route)):
        s = sum(v[:step])
        max_sum = max(s, min_c)
        for idx in range(step, step + len(route) - 1):
            s += v[idx]
            if idx >= step:
                s -= v[idx - step]
            max_sum = max(s, max_sum)
        max_sum_step.append(max_sum)
    addition = k % len(route)
    if full_value > 0:
        addition_value = 0 if addition == 0 else max(max_sum_step[:addition])
        value1 = int(k / len(route)) * full_value + addition_value
        value2 = (int(k / len(route)) - 1) * full_value + max(max_sum_step)
        value = max(value1, value2)
    else:
        value = max(max_sum_step[:min(k, len(max_sum_step))])
    max_value = max(max_value, value)
print(max_value)

Solution (Python):
import sys

n,k=map(int,input().split())

p=list(map(int,input().split()))
c=list(map(int,input().split()))

check=[0 for i in range(n)]

if max(c)<0:
    print(max(c))
    sys.exit()

ans=0

for i in range(n):
    if check[i]==0:
        cnt=0
        check[i]=1
        li=[i]
        pc=p[i]-1
        while pc!=i:
            check[pc]=1
            li.append(pc)
            pc=p[pc]-1
        sumli=0
        for j in li:
            sumli+=c[j]
        add=0
        ki=k
        if k>len(li):
            if sumli>0:
                ki=(ki-1)%len(li)+1
                add=sumli*((k-ki)//len(li))
            else:
                ki=len(li)
        for w in range(1,ki+1):
            sumwmax=0
            sumw=0
            for j in range(w):
                sumw+=c[li[j]]
            for j in range(len(li)):
                sumw=sumw-c[li[j]]+c[li[(j+w)%len(li)]]
                sumwmax=max(sumw,sumwmax)
            cnt=max(cnt,sumwmax)
        ans=max(ans,cnt+add)

print(ans)

Solution (Python):
n,k = map(int, input().split())
p = list(map(int, input().split()))
c = list(map(int, input().split()))

def sim(start,mx): 
    if mx==0:
        return 0
    now_p=0
    nxt=p[start]-1
    cnt=0
    p_lis=[]

    while True:
        nxt=p[nxt]-1
        now_p+=c[nxt]
        p_lis.append(now_p)
        cnt+=1
        if cnt==mx:
            break

    return max(p_lis)

visited_p=set() 
cycle_score=[] 
cycle_points=[]
now_cycle=0

for i in range(n):
    if i in visited_p:
        continue
    visited_p.add(i)
    now_p=0
    nxt=p[i]-1
    visited=set()
    while True:
        nxt=p[nxt]-1
        visited_p.add(nxt)
        if nxt in visited:
            break
        visited.add(nxt)
        now_p+=c[nxt]
    cycle_score.append(now_p)
    cycle_points.append(list(visited))

ans=-float('inf')

for c_num in range(len(cycle_score)):

    cycle_len=len(cycle_points[c_num])
    for start in cycle_points[c_num]:

        if cycle_score[c_num]<0: 
            score = sim(start,min(cycle_len,k))
            ans=max(ans,score)

        else: 
            loop_num = max(0,(k // cycle_len) - 1)
            nokori=k-loop_num*cycle_len
            score = sim(start,nokori) + loop_num*cycle_score[c_num]
            ans=max(ans,score)

print(ans)

Solution (Python):
import sys
import math
from collections import defaultdict
from bisect import bisect_left, bisect_right

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def LI(): return list(map(int, input().split()))
def LIR(row,col):
    if row <= 0:
        return [[] for _ in range(col)]
    elif col == 1:
        return [I() for _ in range(row)]
    else:
        read_all = [LI() for _ in range(row)]
        return map(list, zip(*read_all))



N,K = LI()
P = LI()
C = LI()

for i in range(N):
    P[i] -= 1


ret = [0]*N
for i in range(N):
    p = i
    c = 1
    while True:
        if P[p] == i:
            ret[i] = c
            break
        else:
            p = P[p]
            c += 1

val = [[0]*(N+1) for _ in range(N)]
for i in range(N):
    p = i
    temp = 0
    for j in range(1,N+1):
        p = P[p]
        temp += C[p]
        val[i][j] = temp


ans = -float('inf')
for i in range(N):
    if val[i][ret[i]] <= 0:
        temp_max = max(val[i][1:min(N,K)+1])
    else:
        temp1 = val[i][ret[i]]*(K//ret[i]) + max(val[i][:K-ret[i]*(K//ret[i])+1])
        temp2 = -float('inf')
        if K//ret[i] >= 1:
            temp2 = val[i][ret[i]]*(K//ret[i]-1) + max(val[i][:ret[i]+1])
        temp_max = max(temp1,temp2)
    ans = max(ans,temp_max)

print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(10**7)

readline = sys.stdin.buffer.readline
def readstr():return readline().rstrip().decode()
def readstrs():return list(readline().decode().split())
def readint():return int(readline())
def readints():return list(map(int,readline().split()))
def printrows(x):print('\n'.join(map(str,x)))
def printline(x):print(' '.join(map(str,x)))

def check(cir,num):
    m = len(cir)
    a = sum(cir)
    if num == 0:
        ss = 0
    elif num == 1:
        ss = max(cir)
    else:
        ac = list(accumulate([0]+cir))
        l = 0
        r = 1
        ss = ac[r]-ac[l]
        i = 0
        while 1:
            if r == m:
                l = ac[l+1:r].index(min(ac[l+1:r])) + l+1
                ss = max(ss,ac[r]-ac[l])
                break
            elif i%2==0:
                r = ac[r+1:l+num+1].index(max(ac[r+1:l+num+1])) + r+1
            else:
                l = ac[l+1:r].index(min(ac[l+1:r])) + l+1
            i+=1
            ss = max(ss,ac[r]-ac[l])

        num = m-num
        l = 0
        r = num
        i = 0
        ss = max(ss,a-ac[r]+ac[l])
        while 1:
            if r == m:
                l = ac[l+1:r-num+1].index(max(ac[l+1:r-num+1])) + l+1
                ss = max(ss,a-ac[r]+ac[l])
                break
            elif i%2==0:
                r = ac[r+1:l+m].index(min(ac[r+1:l+m])) + r+1
            else:
                l = ac[l+1:r-num+1].index(max(ac[l+1:r-num+1])) + l+1
            i+=1
            ss = max(ss,a-ac[r]+ac[l])
    return ss


from itertools import accumulate

n,k = readints()
p = [x-1 for x in readints()]
c = readints()

circles = []
used = [0]*n

for i in range(n):
    if not used[i]:
        circles.append([c[i]])
        used[i] = 1
        j = p[i]
        while not used[j]:
            circles[-1].append(c[j])
            used[j] = 1
            j = p[j]

score = -10**20

for cir in circles:
    m = len(cir)
    a = sum(cir)
    if k>m:
        if a>0:
            score = max(score, (k//m)*a + check(cir,k%m), (k//m-1)*a + check(cir,m))
        else:
            score = max(score,check(cir,m))
    else:
        score = max(score,check(cir,k))

print(score)

Solution (Python):
import sys
sys.setrecursionlimit(10**7)

readline = sys.stdin.buffer.readline
def readstr():return readline().rstrip().decode()
def readstrs():return list(readline().decode().split())
def readint():return int(readline())
def readints():return list(map(int,readline().split()))
def printrows(x):print('\n'.join(map(str,x)))
def printline(x):print(' '.join(map(str,x)))

def check(cir,num):
    ans = -10**20
    l = len(cir)
    for start in range(l):
        a = 0
        for i in range(num):
            if start+i == l:
                start = -i
            a += cir[start + i]
            ans = max(ans,a)
    return ans

n,k = readints()
p = [x-1 for x in readints()]
c = readints()

circles = []
used = [0]*n

for i in range(n):
    if not used[i]:
        circles.append([c[i]])
        used[i] = 1
        j = p[i]
        while not used[j]:
            circles[-1].append(c[j])
            used[j] = 1
            j = p[j]

score = -10**20

for cir in circles:
    m = len(cir)
    a = sum(cir)
    if k>m:
        if a>0:
            score = max(score, (k//m)*a + check(cir,k%m), (k//m-1)*a + check(cir,m))
        else:
            score = max(score,check(cir,m))
    else:
        score = max(score,check(cir,k))

print(score)

Solution (Python):



N, K = map(int, input().split())
P = list(map(int, input().split()))
C = list(map(int, input().split()))

ans = -float('inf')
for s in range(N):
    
    S = []  
    
    i = P[s] - 1
    S.append(C[i])
    
    while i != s:
        i = P[i] - 1
        S.append(S[-1] + C[i])

    
    
    if K <= len(S):
        score = max(S[:K])
    
    elif S[-1] <= 0:
        score = max(S)
    
    else:
        
        score1 = S[-1] * (K // len(S) - 1)
        score1 += max(S)
        
        score2 = S[-1] * (K // len(S))
        r = K % len(S)
        if r != 0:
            score2 += max(0, max(S[:r]))
        
        score = max(score1, score2)

    ans = max(ans, score)

print(ans)

Solution (Python):
(n, k), p, c = [[*map(int, i.split())] for i in open(0)]

def solve(x, t):
    visit = [0] * n
    visit[x] = 1
    loop = [0] * n
    count = 0
    ans = c[p[x] - 1]
    l = True
    sub = 0
    while True:
        x = p[x] - 1
        if l:
            if visit[x]:
                if loop[x]:
                    ln = sum(loop)
                    if t > l:
                        sub += (t//ln -1)*count*(count>0)
                        t %= ln
                        t += ln
                    l = False
                count += c[x]
                loop[x] = 1
            visit[x] = 1
        sub += c[x]
        t -= 1
        ans = max(sub, ans)
        if t < 1:
            return ans


print(max(solve(i, k) for i in range(n)))

Solution (Python):
n,k=map(int,input().split())
p=[int(i)-1 for i in input().split()]
c=[int(i) for i in input().split()]
max_c=min(c)

def calc(x):
    global n,k
    next=x
    ma=max_c
    s=0
    l=[]
    for i in range(n):
        next=p[next]
        s+=c[next]
        l.append(c[next])
        ma=max(ma,s)
        if next==x:
            break
    if s<=0:
        return ma

    cycle=k//(i+1)
    rest=k%(i+1)
    ans=(cycle-1)*s+ma
    f=s*cycle
    for j in range(rest):
        f+=l[j]
        ans=max(ans,f)
    return ans

A=max_c
for start in range(n):
    A=max(A,calc(start))
print(A)

Solution (Python):
import sys
sys.setrecursionlimit(10**7)

readline = sys.stdin.buffer.readline
def readstr():return readline().rstrip().decode()
def readstrs():return list(readline().decode().split())
def readint():return int(readline())
def readints():return list(map(int,readline().split()))
def printrows(x):print('\n'.join(map(str,x)))
def printline(x):print(' '.join(map(str,x)))

def check(cir,num):
    m = len(cir)
    a = sum(cir)
    if num == 0:
        ss = 0
    elif num == 1:
        ss = max(cir)
    else:
        ac = list(accumulate([0]+cir))
        l = 0
        r = 1
        ss = ac[r]-ac[l]
        i = 0
        while 1:
            if r == m:
                l = ac[l+1:r].index(min(ac[l+1:r])) + l+1
                ss = max(ss,ac[r]-ac[l])
                break
            elif i%2==0:
                r = ac[r+1:l+num+1].index(max(ac[r+1:l+num+1])) + r+1
            else:
                l = ac[l+1:r].index(min(ac[l+1:r])) + l+1
            i+=1
            ss = max(ss,ac[r]-ac[l])

        num = m-num
        l = 0
        r = num
        i = 0
        ss = max(ss,a-ac[r]+ac[l])
        while 1:
            if r == m:
                l = ac[l+1:r-num+1].index(max(ac[l+1:r-num+1])) + l+1
                ss = max(ss,a-ac[r]+ac[l])
                break
            elif i%2==0:
                r = ac[r+1:l+m].index(min(ac[r+1:l+m])) + r+1
            else:
                l = ac[l+1:r-num+1].index(max(ac[l+1:r-num+1])) + l+1
            i+=1
            ss = max(ss,a-ac[r]+ac[l])
    return ss


from itertools import accumulate

n,k = readints()
p = [x-1 for x in readints()]
c = readints()

circles = []
used = [0]*n

for i in range(n):
    if not used[i]:
        circles.append([c[i]])
        used[i] = 1
        j = p[i]
        while not used[j]:
            circles[-1].append(c[j])
            used[j] = 1
            j = p[j]

score = -10**20

for cir in circles:
    m = len(cir)
    a = sum(cir)
    if k>m:
        if a>0:
            score = max(score, (k//m)*a + check(cir,k%m), (k//m-1)*a + check(cir,m))
        else:
            score = max(score,check(cir,m))
    else:
        score = max(score,check(cir,k))

print(score)