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):
n, k = map(int, input().split())
P = list(map(int, input().split()))
C = list(map(int, input().split()))
score = [0 for _ in range(n)]
loopn = [0 for _ in range(n)]
done = {i: True for i in range(n)}
cycles = []
nux = -1000000000000000
cycles_score = []
for start in range(n):
    if done[start]:
        done[start] = False
        cycle = [start]
        score = C[start]
        nex = P[start]-1
        while nex != start:
            done[nex] = False
            cycle.append(nex)
            score += C[nex]
            nex = P[nex]-1
        cycles.append(cycle)
        cycles_score.append(score)

for score, cycle in zip(cycles_score, cycles):
    l = len(cycle)
    acum = [0 for _ in range(2*l+1)]
    for i in range(2*l):
        acum[i+1] = acum[i]+C[cycle[i % l]]
    if score < 0:
        for r in range(l+1):
            for i in range(l):
                if r == 0:
                    continue
                if r <= k:
                    nux = max(nux, acum[i+r]-acum[i])
    else:
        for r in range(l+1):
            q = (k-r)//l
            for i in range(l):
                if r == 0 and q == 0:
                    continue
                if q <= 0 and r > k:
                    continue
                nux = max(nux, score*q+acum[i+r]-acum[i])


print(nux)

"""n, k = map(int, input().split())
P = list(map(int, input().split()))
C = list(map(int, input().split()))

score = [0 for _ in range(n)]
loopn = [0 for _ in range(n)]
done = {i: True for i in range(n)}
for start in range(n):
    if done[start]:
        nex = -1
        j = 0
        tuuka = []
        nax = -float("inf")
        while nex != start:
            if nex == -1:
                nex = P[start]-1
            else:
                nex = P[nex]-1
            tuuka.append(nex)
            score[start] += C[nex]
            nax = max(nax, score[start])
            j += 1
        loopn[start] = j
        for i in tuuka:
            done[i] = False
            loopn[i] = j
            score[i] = score[start]
            nokori = k-(k//loopn[start])*loopn[start]

    if score[start] < 0:
        score[start] = 0
    else:
        score[start] = (k//loopn[start])*score[start]
        nokori = k-(k//loopn[start])*loopn[start]
        i = 0
        nnnnn = (k//loopn[start])
        nscore = 0
        nax = 0
        while i < nokori:
            nex = P[nex]-1
            nscore += C[nex]
            if nscore < 0:
                break
            nax = max(nax, nscore)
            i += 1
        if nax > 0:
            score[start] += nax


ans = max(score)
if ans <= 0:
    ans = max(C)
print(ans)
"""

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

for i, v in enumerate(P):
    G[i+1] = (v, C[v-1])

ans = -float("inf")

for i in range(1, N+1):
    loop = []
    S = i
    visited = [False for i in range(N+1)]
    while visited[S] == False:
        loop.append(G[S][-1])
        visited[S] = True
        S = G[S][0]

    circle_sum = sum(loop)
    this_case_ans = -float("inf")

    if circle_sum < 0:
        pass_sum = 0
        for i in range(len(loop)):
            pass_sum += loop[i]
            this_case_ans = max(this_case_ans, pass_sum)
        ans = max(ans, this_case_ans)
        continue

    else:
        L = len(loop)
        for i in range(1, L):
            loop[i] += loop[i-1]
        loop.insert(0, -float("inf"))
        for i in range(1, L+1):
            loop[i] = max(loop[i], loop[i-1])
        loop[0] = 0
        if K//L > 0:
            this_case_ans = max(K//L * circle_sum +
                                loop[K % L], (K//L-1)*circle_sum + loop[-1])
        else:
            for i in range(1, K+1):
                this_case_ans = max(this_case_ans, loop[i])
        ans = max(ans, this_case_ans)

print(ans)

Solution (Python):
def getN():
    return int(input())
def getNM():
    return map(int, input().split())
def getList():
    return list(map(int, input().split()))
def getArray(intn):
    return [int(input()) for i in range(intn)]
def input():
    return sys.stdin.readline().rstrip()
def rand_N(ran1, ran2):
    return random.randint(ran1, ran2)
def rand_List(ran1, ran2, rantime):
    return [random.randint(ran1, ran2) for i in range(rantime)]
def rand_ints_nodup(ran1, ran2, rantime):
  ns = []
  while len(ns) < rantime:
    n = random.randint(ran1, ran2)
    if not n in ns:
      ns.append(n)
  return sorted(ns)

def rand_query(ran1, ran2, rantime):
  r_query = []
  while len(r_query) < rantime:
    n_q = rand_ints_nodup(ran1, ran2, 2)
    if not n_q in r_query:
      r_query.append(n_q)
  return sorted(r_query)

from collections import defaultdict, deque, Counter
from sys import exit
from decimal import *
from heapq import heappop, heappush
from math import sqrt
from fractions import gcd
import random
import string
import copy
from itertools import combinations, permutations, product
from operator import mul, itemgetter
from functools import reduce
from bisect import bisect_left, bisect_right

import sys
sys.setrecursionlimit(1000000000)
mod = 10 ** 9 + 7





class Roop:
    def __init__(self, array):
        self.n = len(array)
        self.array = array
        
        self.roops = []
        
        self.roop_dict = [-1] * self.n
        
        self.opt_dic = [-1] * self.n
        ignore = [-1] * self.n
        cnt = 0
        for i in range(self.n):
            if ignore[i] >= 0:
                continue
            opt = [i]
            
            self.opt_dic[i] = 0
            c = 1
            
            ignore[i] = cnt
            
            to = array[i]
            
            while True:
                if ignore[to] >= 0:
                    
                    if ignore[to] < cnt:
                        break
                    
                    for j in range(self.opt_dic[to], len(opt)):
                        self.roop_dict[opt[j]] = cnt
                    self.roops.append(opt[self.opt_dic[to]:])
                    
                    cnt += 1
                    break
                opt.append(to)
                ignore[to] = cnt
                self.opt_dic[to] = c
                c += 1
                to = array[to]

    
    def roop_n(self, x):
        return self.roop_dict[x]

    
    
    def inspect(self, x):
        if self.roop_n(x) == -1:
            return False
        return self.roops[self.roop_dict(x)]

    
    def roop_len(self, x):
        return len(self.roops[self.roop_n(x)])

    
    def move(self, x, k):
        cnt = k
        to = x
        
        
        head = []
        
        tail = []
        
        time = -1
        res = 0
        while cnt > 0:
            to = self.array[to]
            cnt -= 1
            
            if time == -1 and self.roop_n(to) >= 0:
                r = self.roops[self.roop_n(to)]
                time = (cnt // len(r))
                cnt -= time * len(r)
            
            if time == -1:
                head.append(to)
            
            else:
                tail.append(to)
        
        
        
        
        
        
        
        return to

"""
N, A = getNM()
A -= 1
K = getN()
B = [i - 1 for i in getList()]
roop = Roop(B)
print(roop.move(A, K) + 1)

"""

"""

N, K = getNM()
N -= 1
A = [i - 1 for i in getList()]
roop = Roop(A)
print(roop.move(0, K) + 1)
"""



N, K = getNM()
P = [i - 1 for i in getList()]
C = getList()

roop = Roop(P)


ans = -float('inf')
for r in roop.roops:
    n = len(r)
    
    alta = []
    for i in range(n):
        alta.append(C[r[i]])
    
    one_roop = sum(alta)
    alta += alta
    imos = [0]
    for i in range(len(alta)):
        imos.append(imos[i] + alta[i])

    t = min(n, K)
    for i in range(n):
        
        for j in range(1, t + 1):
            if one_roop >= 0:
                opt = (imos[i + j] - imos[i]) + ((K - j) // n) * one_roop
            else:
                opt = imos[i + j] - imos[i]
            ans = max(ans, opt)

print(ans)

Solution (Python):
def solve_loop(loop, K):
    S = sum(loop)
    L = len(loop)
    if S < 0:
        acc = 0
        K = min(K, L)
        minL = 1
    elif K//L >= 2:
        acc = S * (K//L - 1)
        K = K - L * (K//L - 1)
        minL = 0
    else:
        acc = 0
        minL = 1

    ans = -10 ** 9 - 1
    for i in range(L):
        
        tmp = 0
        if minL:
            tmp = loop[i]

        for l in range(minL, K):
            ans = max(tmp, ans)
            tmp += loop[(i+l) % L]
            
            
        ans = max(tmp, ans)

    
    return acc + ans
    if K >= L:
        return max(acc, acc + ans)
    else:
        return ans

def solve():
    N, K = map(int, input().split())
    P = list(map(lambda n: int(n)-1, input().split())) 
    C = list(map(int, input().split()))

    flag = [False] * N
    ans = -10**9-1  
    for i in range(N):
        if flag[i]:
            continue
        loop = []
        j = P[i]
        for _ in range(N):
            if flag[j]: 
                break
            flag[j] = True
            loop += [C[j]]
            j = P[j]
        ans = max(ans, solve_loop(loop, K))
    print(ans)

solve()

Solution (Python):
'''
4 4
4 1 2 3
-19 4 10 6

4 5
4 1 2 3
-19 4 10 6

4 8
4 1 2 3
-19 4 10 6
'''
n, k = map(int, input().split())
p = list(map(int, input().split()))
p = [i-1 for i in p]
c = list(map(int, input().split()))

minusOnly = True
for i in range(n):
    if c[i] > 0:
        minusOnly = False
        break

if minusOnly:
    print(max(c))
    exit()

ans = 0
used = [False]*n

for st in range(n):
    if not used[st]:
        gr = []
        now = st
        gr.append(st)
        used[st] = True
        while True:
            now = p[now]
            gr.append(now)
            used[now] = True
            if now == st:
                break
        gr.pop()

        cs = [c[i] for i in gr]
        s = sum(cs)
        point = 0
        r = k
        if r > 2*len(gr):
            if s > 0:
                point += s*(k//len(gr)-1)
                r -= len(gr)*(k//len(gr)-1)
            else:
                r = 2*len(gr)
        
        cs = cs + cs + cs
        plus = 0
        for i in range(len(gr)):
            nowSum = 0
            for g in range(r):
                nowSum += cs[i+g]
                plus = max(plus, nowSum)
        
        point += plus
        ans = max(ans, point)

print(ans)

Solution (Python):
N,K = map(int,input().split())
P = list(map(int,input().split()))
C = list(map(int,input().split()))
answer = -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))
        amari = K%len(S)
        if amari!=0:
            score1 += max(0,max(S[:amari]))
        score2 = S[-1]*(K//len(S)-1)
        score2 += max(S)
        score = max(score1,score2)
    
    answer = max(answer,score)
print(answer)

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

dummy=set()
loop=[]
X=set(range(N))
while len(dummy)!=N:
  a=[]
  k=min(X-dummy)
  a.append(k)
  dummy.add(k)
  l=P[k]-1
  while l!=k:
    a.append(l)
    dummy.add(l)
    l=P[l]-1
  loop.append(a)

ans=-(10**300)
for l in loop:
  temp=0
  s=len(l)
  ssum=0
  k=0
  for i in range(s):
    ssum+=C[l[i]]
  if ssum>0:
    temp+=((K-1)//s)*ssum
    k=K-((K-1)//s)*s
  else:
    k=min(K,s)
  kmax=-(10**300)
  for ii in range(s):
    tempscore=temp
    for jj in range(1,k+1):
      tempscore+=C[l[(ii+jj)%s]]
      if tempscore>kmax:
        kmax=tempscore
  if kmax>ans:
    ans=kmax
print(ans)

Solution (Python):
import sys
INF = 1 << 60
MOD = 10**9 + 7 
sys.setrecursionlimit(2147483647)
input = lambda:sys.stdin.readline().rstrip()
def resolve():
    n, k = map(int, input().split())
    P = list(map(lambda x : int(x) - 1, input().split()))
    C = list(map(int, input().split()))

    
    nexts = [P]
    vals = [C]
    totals = [C]
    for _ in range(60):
        next, val, total = nexts[-1], vals[-1], totals[-1]
        nnext, nval, ntotal = [0] * n, [0] * n, [0] * n
        for i in range(n):
            nnext[i] = next[next[i]]
            nval[i] = val[i] + val[next[i]]
            ntotal[i] = max(total[i], val[i] + total[next[i]])
        nexts.append(nnext)
        vals.append(nval)
        totals.append(ntotal)

    
    ans = -INF
    for now in range(n):
        score = 0
        for d in range(59, -1, -1):
            if k >> d & 1:
                ans = max(ans, score + totals[d][now])
                score += vals[d][now]
                now = nexts[d][now]
    print(ans)
resolve()

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

P = [None] + P
C = [None] + C

all_max = C[1]
for st in range(1, N + 1):
    p = P[st]
    scores = [C[p]]

    while p != st and len(scores) < K:
        p = P[p]
        scores.append(C[p])

    num_elem = len(scores)
    all_sum = sum(scores)

    q, r = divmod(K, num_elem)

    max_ = scores[0]
    temp = scores[0]

    max_r = scores[0]
    temp_r = scores[0]
    for x in range(1, num_elem):
        if x < r:
            temp_r += scores[x]
            max_r = max(max_r, temp_r)

        temp += scores[x]
        max_ = max(max_, temp)

    temp_max = scores[0]
    if all_sum > 0 and q > 0:
        if r > 0:
            temp_max = max(all_sum * (q - 1) + max_, all_sum * q + max_r)
        else:
            temp_max = all_sum * (q - 1) + max_
    else:
        temp_max = max_

    all_max = max(all_max, temp_max)


print(all_max)

Solution (Python):
def getN():
    return int(input())
def getNM():
    return map(int, input().split())
def getList():
    return list(map(int, input().split()))
def getArray(intn):
    return [int(input()) for i in range(intn)]
def input():
    return sys.stdin.readline().rstrip()
def rand_N(ran1, ran2):
    return random.randint(ran1, ran2)
def rand_List(ran1, ran2, rantime):
    return [random.randint(ran1, ran2) for i in range(rantime)]
def rand_ints_nodup(ran1, ran2, rantime):
  ns = []
  while len(ns) < rantime:
    n = random.randint(ran1, ran2)
    if not n in ns:
      ns.append(n)
  return sorted(ns)

def rand_query(ran1, ran2, rantime):
  r_query = []
  while len(r_query) < rantime:
    n_q = rand_ints_nodup(ran1, ran2, 2)
    if not n_q in r_query:
      r_query.append(n_q)
  return sorted(r_query)

from collections import defaultdict, deque, Counter
from sys import exit
from decimal import *
from heapq import heappop, heappush
from math import sqrt
from fractions import gcd
import random
import string
import copy
from itertools import combinations, permutations, product
from operator import mul, itemgetter
from functools import reduce
from bisect import bisect_left, bisect_right

import sys
sys.setrecursionlimit(1000000000)
mod = 10 ** 9 + 7





class Roop:
    def __init__(self, array):
        self.n = len(array)
        self.array = array
        
        self.roops = []
        
        self.roop_dict = [-1] * self.n
        
        self.opt_dic = {}
        ignore = [-1] * self.n
        cnt = 0
        for i in range(self.n):
            if ignore[i] >= 0:
                continue
            opt = [i]
            
            self.opt_dic[i] = 0
            c = 1
            
            ignore[i] = 1
            
            to = array[i]
            
            while True:
                if ignore[to] >= 0:
                    
                    if self.roop_dict[to] >= 0:
                        break
                    
                    for j in range(self.opt_dic[to], len(opt)):
                        self.roop_dict[opt[j]] = cnt
                    if len(opt[self.opt_dic[to]:]) > 0:
                        self.roops.append(opt[self.opt_dic[to]:])
                    
                    cnt += 1
                    break
                opt.append(to)
                ignore[to] = 1
                self.opt_dic[to] = c
                c += 1
                to = array[to]

    
    def roop_n(self, x):
        return self.roop_dict[x]

    
    
    def inspect(self, x):
        if self.roop_n(x) == -1:
            return False
        return self.roops[self.roop_dict(x)]

    
    def roop_len(self, x):
        return len(self.roops[self.roop_n(x)])

    
    def move(self, x, k):
        cnt = k
        to = x
        
        
        head = []
        
        tail = []
        
        time = -1
        res = 0
        while cnt > 0:
            to = self.array[to]
            cnt -= 1
            
            if time == -1 and self.roop_n(to) >= 0:
                r = self.roops[self.roop_n(to)]
                time = (cnt // len(r))
                cnt -= time * len(r)
            
            if time == -1:
                head.append(to)
            
            else:
                tail.append(to)
        
        
        
        
        
        
        
        return to

"""

N, K = getNM()
N -= 1
A = [i - 1 for i in getList()]
roop = Roop(A)
print(roop.move(0, K) + 1)
"""


N, K = getNM()
P = [i - 1 for i in getList()]
C = getList()

roop = Roop(P)


ans = -float('inf')
for r in roop.roops:
    n = len(r)
    
    alta = []
    for i in range(n):
        alta.append(C[r[i]])
    
    one_roop = sum(alta)
    alta += alta
    imos = [0]
    for i in range(len(alta)):
        imos.append(imos[i] + alta[i])

    t = min(n, K)
    for i in range(n):
        
        for j in range(1, t + 1):
            if one_roop >= 0:
                opt = (imos[i + j] - imos[i]) + ((K - j) // n) * one_roop
            else:
                opt = imos[i + j] - imos[i]
            ans = max(ans, opt)

print(ans)

Solution (Python):
n, k = map(int, input().split())
P = [*map(lambda x: int(x)-1, input().split())]
C = [*map(int, input().split())]

score = -10**18
for st in range(n):
    lap_sc = sum_sc = 0
    nx = st
    for lap_cn in range(1, n+1):
        lap_sc += C[nx]
        nx = P[nx]
        if nx == st: break
    lap_sc = max(0, lap_sc)

    for k_cn in range(1, k+1):
        sum_sc += C[nx]
        score = max(score, sum_sc + lap_sc * ((k - k_cn) // lap_cn))
        nx = P[nx]
        if nx == st: break

print(score)

Solution (Python):
import sys, math

def calcweight_tree(N_vertices, edges, times, inf):

    """
    edges: [start, dest, cost] -> [cost, start, end]
    """

    distance = 0

    passed = [False] * N_vertices

    travel_max = -inf
    for i in range(N_vertices):
        if(passed[i] == False):
            distance = 0
            left = i
            cost_sum = 0
            costs = []
            min_distance = inf
            while(True):
                dest = edges[left][1]
                cost = edges[dest][0]
                if(passed[dest]==False):
                    
                    passed[dest] = True
                    cost_sum += cost
                    costs.append(cost_sum)
                    left = dest
                    if(min_distance > cost):
                        min_distance = cost
                else:
                    period = len(costs)
                    increase_period = cost_sum
                    break
            
            remainder = times%period
            cost_minus = [0]
            for j in range(period-1):
                cost_minus.append(costs[j])
            if(increase_period <= 0):
                """
                for j in range(period):
                    costs.append(costs[j]+increase_period)
                maxindex = 0
                maxindex_start = 0
                maxvalue = -inf

                if(remainder==0):
                    remainder += period

                for st in range(period):
                    maxvalue_candidate = max(costs[st:st+period])
                    if(maxvalue_candidate - cost_minus[st] > maxvalue):
                        maxvalue = maxvalue_candidate - cost_minus[st]
                        maxindex = costs[st:st+period].index(maxvalue_candidate) + st
                        maxindex_start = st
                """
                costs_last = []
                
                remainder2 = remainder % period

                
                """
                for j in range(remainder2, period):
                    costs_last.append(costs[j])
                for j in range(0, remainder2):
                    costs_last.append(costs[j]+increase_period)
                for j in range(period):
                    costs_last.append(costs_last[j]+increase_period)
                """
                for j in range(period):
                    costs_last.append(costs[j])
                for j in range(period):
                    costs_last.append(costs_last[j]+increase_period)
                maxvalue = -inf
                
                for j in range(period):
                    maxvalue_candidate = max(costs_last[j:j+period])
                    if(maxvalue_candidate-cost_minus[j] > maxvalue):
                        maxvalue = maxvalue_candidate-cost_minus[j]

                travel_max = max(maxvalue, travel_max)
            else:
                costs_last = []
                
                remainder2 = remainder % period
                times_period = times//period-1
                add_n = times_period * increase_period
                
                for j in range(remainder2, period):
                    costs_last.append(costs[j]+add_n)
                for j in range(0, remainder2):
                    costs_last.append(costs[j]+add_n+increase_period)
                for j in range(period):
                    costs_last.append(costs_last[j]+increase_period)
                maxvalue = -inf
                
                for j in range(period):
                    maxvalue_candidate = max(costs_last[j:j+period])
                    if(maxvalue_candidate-cost_minus[j] > maxvalue):
                        maxvalue = maxvalue_candidate-cost_minus[j]
                travel_max = max(maxvalue, travel_max)






    return travel_max







if(__name__ == "__main__"):
    """
    N = int( input().strip() )
    Length = list( map(int, input().strip().split() ) )

    edges = [ [] for _ in range(N+2) ]
    for i in range(N):
        edges[0].append([0, i]) 
    for i in range(1, N+1):
        edges[i].append([0, N+1])
    for i in range(N):
        edges[i].append([ CList[i]*(-1), PList[i] ])
    """
    N, K= map(int, input().strip().split() )
    PList = list( map(int, input().strip().split() ) )
    CList = list( map(int, input().strip().split() ) )
    inf = 10**10


    N_vertices = N

    edges3 = []
    costs = []
    for i in range(N):
        edges3.append([ CList[i], PList[i]-1 ])

    weight = calcweight_tree(N_vertices, edges3, K, inf)

    


    print( weight)

Solution (Python):
n, k = map(int, input().split())
P = [*map(lambda x: int(x)-1, input().split())]
C = [*map(int, input().split())]

score = -10**18
for st in range(n):
    lap_sc = sum_sc = 0
    nx = st
    for lap_cn in range(1, max(n, k)+1):
        lap_sc += C[nx]
        nx = P[nx]
        if nx == st: break
    lap_sc = max(0, lap_sc)

    for k_cn in range(1, k+1):
        sum_sc += C[nx]
        score = max(score, sum_sc + lap_sc * ((k - k_cn) // lap_cn))
        nx = P[nx]
        if nx == st: break

print(score)

Solution (Python):
n, k = map(int, input().split())
P = [*map(lambda x: int(x)-1, input().split())]
C = [*map(int, input().split())]

score = -10**18
for st in range(n):
    lap_cn = lap_sc = sum_sc = 0
    nx = st
    while True:
        lap_cn += 1
        lap_sc += C[nx]
        nx = P[nx]
        if nx == st: break
    lap_sc = max(0, lap_sc)

    for k_cn in range(1, k+1):
        sum_sc += C[nx]
        score = max(score, sum_sc + lap_sc * ((k - k_cn) // lap_cn))
        nx = P[nx]
        if nx == st: break

print(score)

Solution (Python):
n, k = map(int, input().split())
P = [*map(lambda x: int(x)-1, input().split())]
C = [*map(int, input().split())]

score = -10**18
for st in range(n):
    lap_cn = 0
    lap_sc = 0
    nx = st
    while True:
        lap_cn += 1
        lap_sc += C[nx]
        nx = P[nx]
        if nx == st: break
    lap_sc = max(0, lap_sc)

    sum_sc = 0
    for k_cn in range(k):
        sum_sc += C[nx]
        score = max(score, sum_sc + lap_sc * ((k - (k_cn + 1)) // lap_cn))
        nx = P[nx]
        if nx == st: break

print(score)

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

def mi(): return map(int,input().split())
def ii(): return int(input())
def isp(): return input().split()
def deb(text): print("-------\n{}\n-------".format(text))

INF=10**20
def main():
    N,K=mi()
    P=list(mi())
    C=list(mi())

    ans = -INF
    for i in range(N):
        start = i + 1 
        stack = [start]
        score_his = [0]
        scores = 0
        depth = 1
        seen = {}
        while stack:
            if depth > K: break
            current = stack.pop()
            
            if current in seen:
                loop_start_depth = seen[current]
                loop_end_depth = depth - 1 
                loop_scores = score_his[-1] - score_his[loop_start_depth-1]
                loop_len = loop_end_depth - loop_start_depth + 1
                if loop_scores < 0: break

                
                
                
                rest_count = K - depth + 1
                available_loop_count = rest_count // loop_len
                res1 = (available_loop_count-1) * loop_scores + scores

                
                
                res2 = res1
                rest_loop_len = rest_count % loop_len + loop_len

                
                ress = [res1,res2]
                for j in range(rest_loop_len):
                    score = C[P[current-1]-1]
                    res2 += score
                    ress.append(res2)
                    current = P[current-1]

                
                score_his.append(max(ress))

                break

            
            score = C[P[current-1]-1]
            scores += score
            score_his.append(scores)

            seen[current] = depth
            stack.append(P[current-1])

            depth += 1
        
        ans = max(ans,max(score_his[1:]))
    
    print(ans)





if __name__ == "__main__":
    main()

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

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

ans = -10 ** 18
for si in range(N):
    x = si
    c = []
    tot = 0
    while True:
        x = P[x]
        c.append(C[x])
        tot += C[x]
        if x == si:
            break

    s = 0
    for k in range(len(c)):
        if k + 1 > K:
            break
        s += c[k]
        ss = s
        if tot > 0:
            ss += tot * int((K - (k + 1)) // len(c))
        ans = max(ss, ans)

print(ans)

Solution (Python):
import sys
import numpy as np







def main(N,K,P,C,ans):


	
	
	cycleIDs = np.full( N, -1, dtype=np.int64 )
	cycleInfs = []


	

	cycleID = 0

	for n in range(N):

		v = n
		currentCycleItemCnt = 0
		currentCycleTotal = 0

		if cycleIDs[v] != -1:
			currentCycleItemCnt, currentCycleTotal = cycleInfs[ cycleIDs[v] ]
			
		else:
			while True:
				
				currentCycleItemCnt += 1
				currentCycleTotal += C[v]

				v = P[v]
				if v == n:
					
					cycleInfs.append( (currentCycleItemCnt, currentCycleTotal) )
					cycleID += 1
					break

				
				
				cycleIDs[v] = cycleID

		procCnt = 0
		currentCycleSumTmp = 0

		while True:

			
			
			procCnt += 1
			currentCycleSumTmp += C[v]
			if K < procCnt:
				break

			cycleLoopCnt = 0
			if procCnt < K and 0 < currentCycleTotal:
				cycleLoopCnt = int(( K - procCnt ) // currentCycleItemCnt)

			
			tmp = currentCycleSumTmp + cycleLoopCnt * currentCycleTotal
			ans = max( int(ans), int(tmp) )

			v = P[v]
			if v == n:
				
				break

	print(int(ans))

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



if __name__ == "__main__":
	N,K = map(int,input().split())
	P = np.array( input().split(), np.int64 )
	P -= 1
	C = np.array( input().split(), np.int64 )

	ans = -1e9	
	main(N,K,P,C,ans)