CodeEff/ECCO huggingface dataset:
# Original solution
import sys
import resource
sys.setrecursionlimit(10000)
n,k=list(map(int,input().rstrip().split()))
p=list(map(int,input().rstrip().split()))
c=list(map(int,input().rstrip().split()))
def find(start,now,up,max,sum,count,flag):
    if start==now:
        flag+=1
    if start==now and flag==2:
        return [max,sum,count]
    elif count==up:
        return [max,sum,count]
    else:
        count+=1
        sum+=c[p[now-1]-1]
        if max<sum:
            max=sum
        return find(start,p[now-1],up,max,sum,count,flag)
kara=[-10000000000]
for i in range(1,n+1):
    m=find(i,i,n,c[p[i-1]-1],0,0,0)
    if m[2]>=k:
        m=find(i,i,k,c[p[i-1]-1],0,0,0)
        if m[0]>kara[0]:
            kara[0]=m[0]
    elif m[1]<=0:
        if m[0]>kara[0]:
            kara[0]=m[0]
    else:
        w=k%m[2]
        if w==0:
            w=m[2]
        spe=find(i,i,w,c[p[i-1]-1],0,0,0)[0]
        if m[1]+spe>m[0] and m[1]*(k-w)//m[2]+spe>kara[0]:
            kara[0]=m[1]*(k-w)//m[2]+spe
        elif m[1]+spe<=m[0] and m[1]*((k-w)//m[2]-1)+m[0]>kara[0]:
            kara[0]=m[1]*((k-w)//m[2]-1)+m[0]
print((kara[0]))

# Optimized solution
import sys
import resource
sys.setrecursionlimit(10000)
n,k=list(map(int,input().rstrip().split()))
p=list(map(int,input().rstrip().split()))
c=list(map(int,input().rstrip().split()))
def find(start,now,up,max,sum,count,flag):
    if start==now:
        flag+=1
    if start==now and flag==2:
        return [max,sum,count]
    elif count==up:
        return [max,sum,count]
    else:
        count+=1
        sum+=c[p[now-1]-1]
        if max<sum:
            max=sum
        return find(start,p[now-1],up,max,sum,count,flag)
kara=[-10000000000]
for i in range(1,n+1):
    m=find(i,i,n,c[p[i-1]-1],0,0,0)
    if m[2]>=k:
        m=find(i,i,k,c[p[i-1]-1],0,0,0)
        if m[0]>kara[0]:
            kara[0]=m[0]
        result=kara[0]
    elif m[1]<=0:
        if m[0]>kara[0]:
            kara[0]=m[0]
        result=kara[0]
    else:
        w=k%m[2]
        if w==0:
            w=m[2]
        spe=find(i,i,w,c[p[i-1]-1],0,0,0)[0]
        if m[1]+spe>m[0] and m[1]*(k-w)//m[2]+spe>kara[0]:
            kara[0]=m[1]*(k-w)//m[2]+spe
        elif m[1]+spe<=m[0] and m[1]*((k-w)//m[2]-1)+m[0]>kara[0]:
            kara[0]=m[1]*((k-w)//m[2]-1)+m[0]
        result=kara[0]
print(result)
# Original solution
(N, K) = [int(x) for x in input().split()]
P = [int(x) - 1 for x in input().split()]  # 0 indexed
C = [int(x) for x in input().split()]


inf = float("inf")


ans = max(C)  # at least one move
for pos in range(N):
    i = pos
    score = 0
    cycleLen = None
    cycleGain = None
    bestInc = 0
    for k in range(K):
        i = P[i]
        score += C[i]
        ans = max(ans, score)
        bestInc = max(bestInc, score)

        if cycleLen is not None and k == K % cycleLen:
            numCycles = (K - k) // cycleLen

            ans = max(ans, cycleGain * numCycles + bestInc)
            break

        if i == pos:
            cycleLen = k
            cycleGain = score

print(ans)


# Optimized solution
(N, K) = [int(x) for x in input().split()]
P = [int(x) - 1 for x in input().split()]  # 0 indexed
C = [int(x) for x in input().split()]


inf = float("inf")


ans = max(C)  # at least one move
for pos in range(N):
    i = pos
    score = 0
    cycleLen = None
    cycleGain = None
    bestInc = 0
    k = 0
    while k < K:
        i = P[i]
        score += C[i]
        ans = max(ans, score)

        if i == pos:
            cycleLen = k + 1
            numCycles = max(0, (K - k - cycleLen) // cycleLen)
            if k + numCycles * cycleLen < K:
                k += numCycles * cycleLen
                score += numCycles * score
        k += 1

print(ans)
# Original solution
from collections import deque
import sys, copy,itertools
input = sys.stdin.readline

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

POINT = [[-10**12 for i in range(n)] for j in range(k)]
PLACE = [[0 for i in range(n)] for j in range(k)]
for i in range(n):
  POINT[0][i] = C[P[i]-1]  
  PLACE[0][i] = P[i]-1 #P[i]は1スタートなのでずれる
  #A[0][i] = C[P[i]]
#print(PLACE)
#print(POINT)

tempmax= max(POINT[0])

for j in range(1,k): #日付
  for i in range(n):
    PLACE[j][i]=P[PLACE[j-1][i]]-1
    POINT[j][i]=POINT[j-1][i] + C[PLACE[j][i]]
    tempmax = max(tempmax,POINT[j][i])

#print(PLACE)
#print(POINT)
print(tempmax)

# Optimized solution
from collections import deque
import sys, copy,itertools
input = sys.stdin.readline

n, k = list(map(int,input().split()))
#P = list(map(int,input().split()))
P = list([int(x) - 1 for x in input().split()]) #ひとつづつずらす
C = list(map(int,input().split()))
SCORE = [0]*(n+1)

max_score = -10**12
for i in range(n):
  x = i
  TEMPMAX = [-10**9] * (n+1)
  for j in range(1, n+1):
    SCORE[j] = SCORE[j-1] + C[P[x]]
    TEMPMAX[j]= max(TEMPMAX[j-1], SCORE[j])
    x = P[x]
    if x == i:
      break
  if j >= k:
    max_score = max(max_score,TEMPMAX[k])
  elif SCORE[j] < 0:
    max_score = max(max_score, TEMPMAX[j])
  else:
    m = k//j
    a = SCORE[j] *(m-1) + TEMPMAX[j]
    b = SCORE[j] *m + TEMPMAX[k % j]
    max_score = max(max_score, a, b)
print(max_score)
# Original solution
import sys
input = sys.stdin.readline
n, k = list(map(int, input().split()))
p = list(map(int, input().split()))
p = [0] + p
c = list(map(int, input().split()))
c = [0] + c
score = [[0] * (n + 1) for _ in range(n + 1)]
# score[i][j]: iからstartしてj回移動した時のスコア
l_cycle = [0] * (n + 1)
for i in range(1, n + 1):
    start = i
    move_cnt = 0
    nxt = i
    while move_cnt < n:
        nxt = p[nxt]
        score[i][move_cnt + 1] += score[i][move_cnt] + c[nxt]
        move_cnt += 1
        if nxt == start:
            l_cycle[start] = move_cnt
            break
# for i in range(1, n + 1):
#     print(score[i])
# print('l_cycle', l_cycle)
ans = -float('inf')
for s in range(1, n + 1):
    if k <= l_cycle[s]:
        # サイクルを回らないので
        temp = max(score[s][1:k + 1])
        ans = max(ans, temp)
        continue
    # 以降は一周以上出来る時

    # 一周以下でやめる場合を探索
    temp = max(score[s][1:l_cycle[s] + 1])
    ans = max(ans, temp)
    # if score[s][l_cycle[s]] <= 0:
    #     # 周回する意味がない
    #     continue
    sk = k // l_cycle[s]  # 何周出来るか
    remk = k % l_cycle[s]
    temp = sk * score[s][l_cycle[s]]  # 周回によるスコア
    if remk != 0:
        temp += max(score[s][1:remk + 1])
    ans = max(ans, temp)

print(ans)


# Optimized solution
n, k = list(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 = -float('inf')
for st in range(n):
    x = st
    score = []
    tot = 0
    while True:
        x = p[x]
        score.append(c[x])
        tot += c[x]
        if x == st:
            break
    l = len(score)
    now = 0
    t = 0
    for i in range(l):
        t += score[i]
        if i + 1 > k:
            break
        now = t
        if tot > 0:
            cycle_num = (k - (i + 1)) // l
            now += tot * cycle_num
        ans = max(ans, now)
print(ans)
# Original solution
from itertools import accumulate


def main():
    cells, moves = [int(x) for x in input().split()]
    jumps_from = [int(x) - 1 for x in input().split()]
    score_on = [int(x) for x in input().split()]

    ans = - 10**10
    for start in range(cells):
        route = []
        route_append = route.append
        position = start
        while True:
            route_append(score_on[position])
            position = jumps_from[position]
            if position == start:  # Looped
                break

        length = len(route)
        total = sum(route)
        accum_tmp = 0
        for i, score in enumerate(route):
            accum_tmp += score
            if i + 1 > moves:
                break
            accum = accum_tmp
            if total > 0:
                accum += total * ((moves - (i + 1)) // length)
            ans = max(ans, accum)

        # if total > 0:
        #     q, mod = divmod(moves, length)
        #     if mod == 0:
        #         candidate = total * q
        #     else:
        #         candidate = max(list(accumulate(route))[:mod]) + total * q
        # else:
        #     candidate = max(list(accumulate(route))[:min(moves, length)])
        # ans = max(ans, candidate)
    return ans


if __name__ == '__main__':
    ans = main()
    print(ans)


# Optimized solution
def main():
    cells, can_jump = [int(x) for x in input().split()]
    jumps_from = [int(x) - 1 for x in input().split()]
    score_on = [int(x) for x in input().split()]

    ans = - 10**10
    for start in range(cells):
        route = []
        position = start
        while True:
            route.append(score_on[position])
            position = jumps_from[position]
            if position == start:  # Looped
                break

        length = len(route)
        total = sum(route)
        accum_tmp = 0
        for jumping, score in enumerate(route):
            accum_tmp += score
            if jumping + 1 > can_jump:
                break
            accum = accum_tmp
            if total > 0:
                accum += total * ((can_jump - (jumping + 1)) // length)
            ans = max(ans, accum)
    return ans


if __name__ == '__main__':
    ans = main()
    print(ans)
# Original solution
n, k = list(map(int, input().split()))
P = [*[int(x)-1 for x in input().split()]]
C = [*list(map(int, input().split()))]

INF = 10**18
score = -INF
for st in range(n):
    tot = 0 # cost of one lap
    costs = []
    nx = st
    while True:
        nx = P[nx]
        costs.append(C[nx])
        tot += C[nx]
        if nx == st: break

    lap_c = -INF # lap costs
    r = k
    if tot >= 0:
        nl, r = divmod(k, len(costs)) # number of loops
        lap_c = max(lap_c, tot * nl)
        # print('nl {}, k {}'.format(nl, k))

    sum_c = 0
    max_c = -INF
    for c in costs[:min(r, len(costs))]:
        sum_c += c
        max_c = max(max_c, sum_c)

    score = max(score, lap_c, max_c, lap_c + max_c)

    # print(st, costs, tot)
    # print(lap_c, max_c, lap_c+max_c, '=', score)

print(score)

# print('===')
# print(n,k)
# print(P)
# print(C,end='\n\n')


# Optimized solution
n, k = list(map(int, input().split()))
P = [*[int(x)-1 for x in input().split()]]
C = [*list(map(int, input().split()))]

INF = 10**18
max_score = -INF
for st in range(n):
    lc = 0 # lap count
    lap_sc = 0 # lap score
    nx = st
    while True:
        lc += 1
        lap_sc += C[nx]
        nx = P[nx]
        if nx == st: break

    sum_sc = 0
    kc = 0
    while True:
        kc += 1
        if k < kc: break

        sum_sc += C[nx]
        score = sum_sc + max(0, lap_sc) * ((k - kc) // lc)
        max_score = max(max_score, score)

        nx = P[nx]
        if nx == st: break

print(max_score)

# print('===')
# print(n,k)
# print(P)
# print(C,end='\n\n')
# Original solution
n, k = list(map(int, input().split()))
P = [*[int(x)-1 for x in input().split()]]
C = [*list(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)


# Optimized solution
n, k = list(map(int, input().split()))
P = [*[int(x)-1 for x in input().split()]]
C = [*list(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)
# Original solution
n, k = list(map(int, input().split()))
ps = list(map(int, input().split()))
cs = list(map(int, input().split()))
ps = [p-1 for p in ps]
visited = [False] * n
from collections import deque
ds = []
sums = []
for i in range(n):
    if visited[i]: continue
    q = deque([])
    q.append(i)
    s = cs[i]
    d = [i]
    while len(q) > 0:
        u = q.popleft()
        visited[u] = True
        nx = ps[u]
        if visited[nx]: continue
        d.append(nx)
        q.append(nx)
        s += cs[nx]
    sums.append(s)
    ds.append(d)

# print(ds,sums)
from itertools import accumulate
def calcmax(d,s,k,cs):
    cnt = 0
    l = len(d)
    div, rest_ = divmod(k-1, l)
    rest_ += 1
    if s > 0:
        cnt += div*s
    d2 = d*2
    c_ = [cs[j] for j in d2]
    acc = list(accumulate(c_))
    mx = - 1<<50
    if s < 0:
        for rest in range(1,l+1):
            for i in range(rest,l*2):
                c = acc[i] - acc[i-rest]
                mx = max(mx,c)
        return mx
    for rest in range(1,rest_+1):
        for i in range(rest,l*2):
            c = acc[i] - acc[i-rest]
            # print(i,rest,c,"debug")
            mx = max(mx, c)
    # print(d,cnt,mx)
    return cnt + mx

ans = -1 << 50
for d,s in zip(ds,sums):
    # print("aaa",d,s)
    c = calcmax(d,s,k,cs)
    ans = max(ans,c)
print(ans)

# Optimized solution
n, k = list(map(int, input().split()))
ps = list(map(int, input().split()))
cs = list(map(int, input().split()))
ps = [p-1 for p in ps]
# doubling使う
vers = []   # vers[b][i] 頂点iから2^b回移動した時にどの頂点にいるか
score = []  # score[b][i]頂点iから2^b回移動した時に何点もらえるか
vers.append(ps)
score.append(cs)

m = 31
# ダブリング
for b in range(1, m+1):
    p_bth = [0] * n
    c_bth = [0] * n
    for i in range(n):
        p_bth[i] = vers[b-1][vers[b-1][i]]
        c_bth[i] = score[b-1][i] + score[b-1][vers[b-1][i]]
    vers.append(p_bth)
    score.append(c_bth)

# 桁DP
MIN = -(1 << 63) 
prv = [[MIN, 0] for _ in range(n)]
nxt = [[MIN, MIN] for _ in range(n)] 
for b in range(m, -1, -1):
    for i in range(n):
        if (k >> b) & 1:
            nxt[vers[b][i]][0] = max(nxt[vers[b][i]][0], prv[i][0] + score[b][i])
            nxt[vers[b][i]][1] = max(nxt[vers[b][i]][1], prv[i][1] + score[b][i])
            nxt[i][0] = max(nxt[i][0], prv[i][0], prv[i][1])
        else:
            nxt[vers[b][i]][0] = max(nxt[vers[b][i]][0], prv[i][0] + score[b][i])
            nxt[i][0] = max(nxt[i][0], prv[i][0])
            nxt[i][1] = max(nxt[i][1], prv[i][1])
    prv, nxt = nxt, prv

ans = max(max(x) for x in prv)
if ans == 0:
    ans = max(cs)
print(ans)
# Original solution
int1 = lambda x: int(x) - 1

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

visited = set()
cycles = []
for i in range(N):
    if i not in visited:
        cur = P[i]
        cycle = [i]
        while cur != i:
            visited.add(cur)
            cycle.append(cur)
            cur = P[cur]
        cycles.append(cycle)

ans = -float('inf')
for cycle in cycles:
    score = [0]
    for x in cycle * 2:
        score.append(score[-1] + C[x])

    # i回進めるときのスコア最大値
    lst = [0] * (min(K, len(cycle)) + 1)
    lst[0] = -float('inf')
    for i in range(1, min(K, len(cycle)) + 1):
        tmp = -float('inf')
        for j in range(len(cycle)):
            tmp = max(tmp, score[j + i] - score[j])
        lst[i] = tmp

    lap = K // len(cycle)
    if lap == 0:
        ans = max(ans,
                  max(lst))
    else:
        around_score = lst[len(cycle)]
        ans = max(ans,
                  max(lst),
                  around_score * (lap - 1) + max(lst),
                  around_score * lap + max(lst[:K % len(cycle) + 1]))
print(ans)


# Optimized solution
int1 = lambda x: int(x) - 1

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

visited = set()
cycles = []
for i in range(N):
    if i not in visited:
        cur = P[i]
        cycle = [i]
        while cur != i:
            visited.add(cur)
            cycle.append(cur)
            cur = P[cur]
        cycles.append(cycle)

ans = -float('inf')
for cycle in cycles:
    l = len(cycle)
    score = [0]
    for x in cycle * 2:
        score.append(score[-1] + C[x])

    # i回進めるときのスコア最大値
    lst = [0] * (min(K, l) + 1)
    lst[0] = -float('inf')
    for i in range(1, min(K, l) + 1):
        tmp = -float('inf')
        for j in range(l):
            tmp = max(tmp, score[j + i] - score[j])
        lst[i] = tmp

    lap = K // l
    if lap == 0:
        ans = max(ans,
                  max(lst))
    else:
        around_score = lst[l]
        ans = max(ans,
                  max(lst),
                  around_score * (lap - 1) + max(lst),
                  around_score * lap + max(lst[:K % l + 1]))
print(ans)
# Original solution
n, k =list(map(int, input().split()))
p = list(map(int, input().split()))
c = list(map(int, input().split()))
roop = []
seen = [0 for  _ in range(n)]
count = 0
for i in range(n):
    if seen[i]>0:
        continue
    else:
        count+=1
        seen[i] = count
        roop.append([c[i]])
        t = i
        while i!=p[t]-1:
            seen[p[t]-1]=count
            roop[-1].append(c[p[t]-1])
            t = p[t]-1
#print(seen)
#print(roop)
ans = max(c)
for i in roop:
    ii = i+i
    if len(i)>=k:
        for j in range(1, k+1):
            for l in range(len(i)):
                temp = sum(ii[l:l+j])
                #print(i, j, l, temp)
                ans  = max(ans, temp)
    else:
        for j in range(1, len(i)+1):
            for l in range(len(i)):
                if sum(i)>0:
                    temp = sum(ii[l:l+j])+(sum(i)*((k-j)//len(i)))
                else:
                    temp = sum(ii[l:l+j])
                #print(i, j, l, temp)
                ans  = max(ans, temp)
            
print(ans)

        

# Optimized solution
n, k =list(map(int, input().split()))
p = list(map(int, input().split()))
c = list(map(int, input().split()))
roop = []
seen = [0 for  _ in range(n)]
count = 0
for i in range(n):
    if seen[i]>0:
        continue
    else:
        count+=1
        seen[i] = count
        roop.append([c[i]])
        t = i
        while i!=p[t]-1:
            seen[p[t]-1]=count
            roop[-1].append(c[p[t]-1])
            t = p[t]-1
#print(seen)
#print(roop)
ans = max(c)

for i in roop:
    #print(ans)
    
    s = sum(i)
    ii = i+i
    #print(ii)
    if len(i)>=k:
        for j in range(1, k+1):
            temp = sum(ii[:j])
            for l in range(len(i)):
                if l!=0:
                    temp+=ii[l+j-1]
                    temp-=ii[l-1]
                    #temp = sum(ii[l:l+j])
                #print(i, j, l, temp)
                ans  = max(ans, temp)
    else:
        for j in range(1, len(i)+1):
            temp=  sum(ii[:j])
            for l in range(len(i)):
                if l != 0:
                    temp+=ii[l+j-1]
                    temp-=ii[l-1]
                #print(temp)
                if s>0:
                    temp1 = temp+s*((k-j)//len(i))
                else:
                    temp1 = temp
                
                #print(i, j, l, temp)
                ans  = max(ans, temp)
                ans  = max(ans, temp1)
            
print(ans)
# Original solution
n, k = list(map(int, input().split()))
p = list(map(int, input().split()))
c = list(map(int, input().split()))
s = [[0] for _ in range(n)]
ans = -10**18
 
for i in range(n):
    flag = 0
    a = p[i]
    s[i].append(c[a-1])
    while flag == 0:
        a = p[a-1]
        if a == i + 1:
            flag = 1
        s[i].append(c[a-1]+ s[i][-1])
 
for i in range(n):
    a = 0
    mul = k//(len(s[i])-1)
    m = mul*(s[i][-1] > 0)
    re = k - m*(len(s[i])-1)
 
    a += m*s[i][-1]
    if len(s[i][1:min(re+1, len(s[i])-1)]):
        a += max(s[i][1:min(re+1, len(s[i])-1)])
    
    f = s[i].index(max(s[i][1:-1]))
    al = mul*min(0, m-1) + s[i][f]
    if al > a and m>0:
        a = al
    
    if a > ans:
        ans = a
print(ans)

# Optimized solution
N, K = list(map(int, input().split()))
P = list(map(int, input().split()))
for i in range(N):
    P[i] -= 1
C = list(map(int, input().split()))
 
ans = -(10 ** 18)
 
for si in range(N):
    x = si
    loop = []
    total = 0
    while 1:
        x = P[x]
        loop.append(C[x])
        total += C[x]
        if x == si:
            break
    T = len(loop)  # 周期の大きさ
    tmp = 0
    for i in range(T):
        tmp += loop[i]
        if K < i + 1:
            break
        now = tmp
        if total > 0:  # loopの和が正ならloopを回した方がお得
            loop_times = (K - (i + 1)) // T  # 何周できるか
            now += total * loop_times
        ans = max(ans, now)
 
print(ans)
# Original solution
n,k=list(map(int,input().split()))

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

check=[0]*n
group=[]

for i in range(n):
    tmp=i
    if check[tmp]==0:
        tmp_group=[]
        while check[tmp]==0:
            tmp_group.append(tmp)
            check[tmp]=1
            tmp=p[tmp]-1

        group.append(tmp_group)

ans="start"

#startの最低とgoalの最高の和
for item in group:
    
    #一周すると何になるか。これはどこスタートでも同じ
    circle=0
    cnt=k
    if len(item)<k:
        for v in item:
            circle+=c[v]
        cnt=k-len(item)
    
    #一周した後のあまりで最強を探す


    goal=(-1)*(10**18)
    
    #startは各groupのindexが入ってる
    for start in range(len(item)):
        tmp=0
        #print("start",item,start,cnt)
        for i in range(start,start+cnt):
            #print(">>",i)
            tmp+=c[item[i%len(item)]]
            #print(item[i%len(item)],c[item[i%len(item)]])
            goal=max(goal,tmp)

    #print(item,circle,goal)
    if ans=="start":
        ans=goal+max(0,circle)
    else:
        ans=max(ans,goal+max(0,circle))

print(ans)














# Optimized solution
n,k=list(map(int,input().split()))

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

group_score=[]
checked=[0]*n

for i in range(n):
    if checked[i]==0:
        tmp_group=[]
        tmp=i
        while checked[tmp]==0:
            checked[tmp]=1
            tmp_group.append(score[tmp])
            tmp=p[tmp]-1
        group_score.append(tmp_group)



#aryの中から連続するk個選択するときの最大
def calc(k):
    if k==0:
        return 0
    global group
    ans="INF"
    for i in range(len(group)):
        tmp=0
        for j in range(k):
            tmp+=group[(i+j)%len(group)]
            if ans=="INF":
                ans=tmp
            else:
                if ans<tmp:
                    ans=tmp
    return ans

ans=score[0]
for group in group_score:
    #一周以上する場合
    if len(group)<k:
        cycle=sum(group)
        if cycle>0:
            cycle_sum=cycle*(k//len(group))
            tmp=calc(k%len(group))
            ans=max(ans,cycle_sum+tmp)

            if k//len(group)>=2:
                cycle_sum=cycle*(k//len(group)-1)
                tmp=calc(len(group))
                ans=max(ans,cycle_sum+tmp)
          

        tmp=calc(len(group))
        ans=max(ans,tmp)



    #一周しない場合k)
    else:
        tmp=calc(k)
        ans=max(ans,tmp)

print(ans)