CodeEff/ECCO huggingface dataset:
# Original solution
n,k = list(map(int, input().split()))
p = list(map(int, input().split())) 
c = list(map(int, input().split()))
r = -10**9
for i in range(n):
  ans=c[i]
  e =[ans]
  f = i
  a = 1
  while a<k:
    i = p[i]-1
    if i == f:
      break
    a+=1
    ans+=c[i]
    e.append(ans)
  if e[-1]>0 and a<k:
    w = k%len(e)
    if w!=0:
      y = k//len(e)*e[-1]+max(e[:w])
    else:
      y =( k//len(e)-1)*e[-1]+max(e)
    g=y
  else:
    g=max(e)
  r = max(r,g)
print(r)

# Optimized solution
n,k = list(map(int, input().split()))
p = list(map(int, input().split())) 
c = list(map(int, input().split()))
g = []
for i in range(n):
  ans=c[i]
  e =[ans]
  f = i
  a = 1
  while a<k:
    i = p[i]-1
    if i == f:
      break
    a+=1
    ans+=c[i]
    e.append(ans)
  if e[-1]>0 and a<k:
    w = k%len(e)
    if w!=0:
      y = k//len(e)*e[-1]+max(e[:w])
    else:
      y =( k//len(e)-1)*e[-1]+max(e)
    g.append(y)
  else:
    g.append(max(e))
print((max(g)))
# Original solution
N,K = list(map(int,input().split()))
P = list(map(int,input().split()))
C = list(map(int,input().split()))

ans = -float('inf')
for i in range(N):
    s = 0
    for k in range(K):
        i = P[i]-1
        s += C[i]
        ans = max(ans, s)
print(ans)

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

ans = -float('inf')
for i in range(N):
    s = 0
    j = i
    for k in range(K):
        j = P[j]-1
        s += C[j]
        ans = max(ans, s)
        if j==i: break
    d,m = divmod(K, k+1)
    if m==0 and d>1:
        m = k+1
        d -= 1
    s *= d
    ans = max(ans, s)
    for k in range(m):
        j = P[j]-1
        s += C[j]
        ans = max(ans, s)

print(ans)
# Original solution
# どう考えてもK>5000でループが起きるので，
# dp[k][i]:= k回まで，移動したときの最大の値とすればよい
# -infで初期化
N,K = list(map(int,input().split()))
P = list(map(int,input().split()))
C = list(map(int,input().split()))

dp = [[-float('inf') for _ in range(N)] for __ in range(5000)]
for i,c in enumerate(C):
    dp[0][i] = 0
max_val = -float('inf')
if K<(5000-1):
    for i in range(K):
        for j in range(N):
            next_cell = P[j] - 1
            dp[i + 1][next_cell] = max(dp[i][j] + C[next_cell], dp[i + 1][next_cell])
            max_val = max(dp[i + 1][next_cell], max_val)
    print(max_val)
    exit()

for i in range(5000-1):
    for j in range(N):
        next_cell = P[j]-1
        dp[i+1][next_cell] = max(dp[i+1][next_cell] + C[next_cell], dp[i+1][next_cell])
        max_val = max(dp[i+1][next_cell],max_val)
print(max_val)



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

LC = [-1] * N
# Pが順列なので，結局それぞれのマスはループのどれかにいる事がわかる．あとは，ループの長さとループ1回分のコスト(a->a)を計算しておく
# ループ1回分のコストが正の場合はループをなるべく回す．負の場合は1回もループしないほうがいい．ただし最初のa->aは考慮する.
# 1回は最低でも動かないといけないから
max_score = -float('inf')
for i in range(N):
    Loop_len = 0
    Loop_cost =[]
    Loop_cost_sum = 0
    now = i
    while True:
        now = P[now] - 1
        Loop_len += 1
        Loop_cost_sum += C[now]
        Loop_cost.append(Loop_cost_sum)
        if now == i:
            break
    # それぞれのマスへのループによるコストのゲインと,最短でそこへいくまでの移動コストを計算してコストを決定する
    for i,lc in enumerate(Loop_cost):
        if K-(i+1)<0: # 行けないので
            continue
        possible_loop_num = (K-(i+1))//Loop_len
        cost = lc + max(0,Loop_cost_sum) * possible_loop_num
        max_score = max(cost,max_score)

print(max_score)
# Original solution
from collections import defaultdict

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

P = [p - 1 for p in P]
SB = defaultdict(int)

sumC = sum(C) 

# if sumC > 0:
#   d, k = divmod(k, n)
#   if d > 0:
#     pscore = (d - 1) * sumC
#     k += n 
#   else:
#     pscore = 0
# else:
#   k = min(k, n * 2)
pscore = 0

for p in P: 
  cnt = 0
  score = 0
  mv = - 10 ** 19
  s = p
  while cnt < k:
    score += C[s]
    s = P[s]
    cnt += 1
    mv = max(mv, score)
  
  SB[p] = mv

ans = max(SB.values()) + pscore
print(ans)

# Optimized solution
from collections import defaultdict

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

P = [p - 1 for p in P]

# Pの要素の中で循環するモノ同士をまとめる
sep = []
visited = [0] * n
for i in range(n):
  s = i
  box = []
  while visited[s] == 0:
    box.append(s)
    visited[s] = 1
    s = P[s]
  if box != []:
    sep.append(box)

ans = - 10 ** 19
for sp in sep:
  SB = defaultdict(int)
  sumC = sum([C[i] for i in sp]) 
  sn = len(sp)

  if sumC > 0:
    d, mk = divmod(k, sn)
    if d > 0:
      pscore = (d - 1) * sumC
      mk += sn 
    else:
      pscore = 0
  else:
    mk = min(k, sn * 2)
    pscore = 0

  for p in sp: 
    cnt = 0
    score = 0
    mv = - 10 ** 19
    s = p
    while cnt < mk:
      score += C[s]
      s = P[s]
      cnt += 1
      mv = max(mv, score)
    
    SB[p] = mv

  ans = max(ans, max(SB.values()) + pscore)
  
print(ans)
# Original solution
n,k=list(map(int,input().split()))
p=list(map(int,input().split()))
c=list(map(int,input().split()))
ans=-10**9

for i in range(1,n+1):
    m=i
    co=0
    an=0
    for j in range(n):
        m=p[m-1]
        co+=1
        if m==i:
            break      
    m=i
    x=[0 for j in range(co+1)]
    for j in range(co):
        m=p[m-1]
        x[j+1]=x[j]+c[m-1]
    
    if k<=co:
        ans=max(ans,max(x[j] for j in range(1,k+1)))
    else:
        if x[-1]<=0:
            ans=max(ans,max(x[j] for j in range(1,co+1)))
        else:
            f=max(0,k%co-1)
            an+=x[-1]*f
            s=k-f*co
            
            m=i
            for i in range(s):
                m=p[m-1]
                an+=c[m-1]
                ans=max(ans,an)
    
print(ans)
    



# Optimized solution
n,k=list(map(int,input().split()))
p=list(map(int,input().split()))
c=list(map(int,input().split()))
ans=-10**9

for i in range(1,n+1):
    m=i
    co=0
    an=0
    for j in range(n):
        m=p[m-1]
        co+=1
        if m==i:
            break      
    m=i
    x=[0 for j in range(2*co)]
    for j in range(2*co-1):
        m=p[m-1]
        x[j+1]=x[j]+c[m-1]
    
    if k<=co:
        ans=max(ans,max(x[j] for j in range(1,k+1)))
    else:
        if x[co]<=0:
            ans=max(ans,max(x[j] for j in range(1,co+1)))
        else:
            f=max(0,(k//co)-1)
            an+=x[co]*f
            s=k-f*co
            ans=max(ans,an+max(x[j] for j in range(1,s+1)))
            
            
            
            
print(ans)
# Original solution
N, K = list(map(int, input().split()))

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

for i in range(len(p)):
    p[i] -= 1

ans = float("-inf")

for i in range(N):
    #iはスタートポジション
    pos = i
    #移動先のマスにかかれたポイント
    point = []
    total = 0
    while True:
        pos = p[pos]
        point.append(c[pos])
        # totalは周期の和がマイナスかプラスかで後々場合分けするために使う。(周期が負だったら一巡目で終わらせたい。周期が正だったらできる限り後の方で終わらせたい)
        total += c[pos]
        #スタートポジションに戻ってきた==サイクルを検知した
        if pos == i: break
    l = len(point)

    t = 0
    #total<0のときはif total>0以外の処理でまきとれる
    for i in range(l):
        t += point[i]
        #Kがi+1より小さい時のハンドリング
        if i+1 > K: break
        now = t
        if total > 0:
            #K-i-1の-1はポイントの一個目を獲得する時に1個動くので-1。二こ目のポイントを取る時はi=1で、K-2になり計算が合う。それをlでわり周期が何個回れるかを計算する
            #nowはtotalのセットが何個かあって、その先にpoint[i]がくっつくイメージ。[a,b,c] + [a,b,c] + [a,b,c] + ([a] or [a+b] + [a+b+c]) 
            now += (total * ((K-i-1)//l))
        ans = max(ans, now)
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(len(p)):
    p[i] -= 1

ans = float("-inf")

for i in range(N):
    #iはスタートポジション
    pos = i
    #移動先のマスにかかれたポイント
    point = []
    total = 0
    while True:
        pos = p[pos]
        point.append(c[pos])
        # totalは周期の和がマイナスかプラスかで後々場合分けするために使う。(周期が負だったら一巡目で終わらせたい。周期が正だったらできる限り後の方で終わらせたい)
        total += c[pos]
        #スタートポジションに戻ってきた==サイクルを検知した
        if pos == i: break
    l = len(point)

    t = 0
    #total<0のときはif total>0以外の処理でまきとれる
    for i in range(l):
        t += point[i]
        #Kがi+1より小さい時のハンドリング
        if i+1 > K: break
        now = t
        if total > 0:
            #K-i-1の-1はポイントの一個目を獲得する時に1個動くので-1。二こ目のポイントを取る時はi=1で、K-2になり計算が合う。それをlでわり周期が何個回れるかを計算する
            #nowはtotalのセットが何個かあって、その先にpoint[i]がくっつくイメージ。[a,b,c] + [a,b,c] + [a,b,c] + ([a] or [a+b] + [a+b+c]) 
            cnt = (K-i-1) // l
            now += total * cnt 
        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()))

for i in range(len(p)):
    p[i] -= 1

ans = float("-inf")

for i in range(N):
    #iはスタートポジション
    pos = i
    #移動先のマスにかかれたポイント
    point = []
    total = 0
    while True:
        pos = p[pos]
        point.append(c[pos])
        # totalは周期の和がマイナスかプラスかで後々場合分けするために使う。(周期が負だったら一巡目で終わらせたい。周期が正だったらできる限り後の方で終わらせたい)
        total += c[pos]
        #スタートポジションに戻ってきた==サイクルを検知した
        if pos == i: break
    l = len(point)

    t = 0
    #total<0のときはif total>0以外の処理でまきとれる
    for i in range(l):
        t += point[i]
        #Kがi+1より小さい時のハンドリング
        if i+1 > K: break
        now = t
        if total > 0:
            #K-i-1の-1はポイントの一個目を獲得する時に1個動くので-1。二こ目のポイントを取る時はi=1で、K-2になり計算が合う。それをlでわり周期が何個回れるかを計算する
            #nowはtotalのセットが何個かあって、その先にpoint[i]がくっつくイメージ。[a,b,c] + [a,b,c] + [a,b,c] + ([a] or [a+b] + [a+b+c]) 
            #最初now += total * (K-i-1)//lとしていてWAしていたので書き方注意。これだとtotalと(K-i-1)をかけたものをlでわる、となってしまう。
            cnt = (K-i-1) // l
            now += total * cnt 
        ans = max(ans, now)
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(len(P)):
    P[i] -= 1

ans = float("-inf")
for i in range(N):
    cycle = []
    pos = i
    total = 0
    while True:
        pos = P[pos]
        cycle.append(C[pos])
        total += C[pos]
        if pos == i: break

    l = len(cycle)
    t = 0
    for j in range(l):
        t += cycle[j]
        if j + 1 > K: break
        now = t

        if total > 0:
            cnt = (K-j-1) // l
            now += total * cnt
        ans = max(ans, now)
print(ans)
# Original solution
N, K = [int(i) for i in input().split()]
ps = [int(i) for i in input().split()]
cs = [int(i) for i in input().split()]

global_max = -10**10
past_score = [[]]*N
past_time = [[]]*N
for n in range(N):
    score = 0
    itta = set([])
    iru = n
    k = 0
    while k < K:
        score += cs[ps[iru]-1]
        k += 1
        if iru in itta:
            # print('itta')
            # print(f'iru is {iru}')
            # print(f'score is {score}')
            # print(f'past_score is {past_score}')
            if score > past_score[iru]:
                # print('plus loop')
                T = k - past_time[iru]  # 周期
                # print(f'周期は {T}')
                if K - k > (2 * T) + 1:
                    # print(f'繰り返しは{((K-k)//T - 1)}回')
                    # print('それによって', (((K-k)//T - 1)*(score - past_score[iru])))
                    score += (((K-k)//T - 1)*(score - past_score[iru]))
                    k += T * ((K-k)//T - 1)
                    # print(f'new score is {score}')
                    # print(f'new k is {k}')
            else:
                # print('break!')
                break
        itta.add(iru)
        # print(iru)
        # print(ps[iru]-1)
        # print(f'score is {score}')
        global_max = max(score, global_max)
        past_score[iru] = score
        past_time[iru] = k
        iru = ps[iru]-1
print(global_max)


# Optimized solution
N, K = [int(i) for i in input().split()]
ps = [int(i) for i in input().split()]
cs = [int(i) for i in input().split()]

global_max = -10**10
past_score = [[]]*N
past_time = [[]]*N
for n in range(N):
    score = 0
    itta = [0]*N
    iru = n
    k = 0
    while k < K:
        score += cs[ps[iru]-1]
        k += 1
        if itta[iru] == 1:
            # print('itta')
            # print(f'iru is {iru}')
            # print(f'score is {score}')
            # print(f'past_score is {past_score}')
            if score > past_score[iru]:
                # print('plus loop')
                T = k - past_time[iru]  # 周期
                # print(f'周期は {T}')
                if K - k > (2 * T) + 1:
                    # print(f'繰り返しは{((K-k)//T - 1)}回')
                    # print('それによって', (((K-k)//T - 1)*(score - past_score[iru])))
                    score += (((K-k)//T - 1)*(score - past_score[iru]))
                    k += T * ((K-k)//T - 1)
                    # print(f'new score is {score}')
                    # print(f'new k is {k}')
            else:
                # print('break!')
                break
        itta[iru] = 1
        # print(iru)
        # print(ps[iru]-1)
        # print(f'score is {score}')
        global_max = max(score, global_max)
        past_score[iru] = score
        past_time[iru] = k
        iru = ps[iru]-1
print(global_max)
# Original solution
class UnionFind():
    def __init__(self,n):
        self.n=n
        self.root=[-1]*n
        self.rank=[-1]*n

    def Find_Root(self,x):
        if self.root[x]<0:return x
        else:
            self.root[x]=self.Find_Root(self.root[x])
            return self.root[x]

    def Unite(self,x,y):
        x=self.Find_Root(x)
        y=self.Find_Root(y)

        if x==y:return
        elif self.rank[x]>self.rank[y]:
            self.root[x] +=self.root[y]
            self.root[y]=x
        else:
            self.root[y] +=self.root[x]
            self.root[x]=y
            if self.rank[x]==self.rank[y]:
                self.rank[y] +=1

    def isSameGroup(self,x,y):
        return self.Find_Root(x)==self.Find_Root(y)

    def size(self,x):
        return -self.root[self.Find_Root(x)]

    def members(self,x):
        root=self.Find_Root(x)
        return [i for i in range(self.n) if self.Find_Root(i)==root]

    def roots(self):
        return[i for i,j in enumerate(self.root) if j<0]

    def group_members(self):
        return {i:self.members(i) for i in self.roots()}

    def group_count(self):
        return len(self.roots())


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

UnionFind=UnionFind(N+1)
for i in range(N):
    UnionFind.Unite(i+1,P[i])

D=UnionFind.group_members()
E=[]
for i in D:
    A,length=D[i],len(D[i])
    if A[0]==0:continue
    index,F=A[0]-1,[]
    while len(F)!=length:
        index=P[index]-1
        F.append(C[index])
    E.append(F)

ans=-float("inf")
for A in E:
    length=len(A)
    if sum(A)<0:
        A=A*2
        for i in range(length):
            point=0
            for j in range(min(K,length)):
                point +=A[i+j]
                ans=max(ans,point)
    else:
        div,mod=divmod(K,length)
        base=(div-1)*sum(A)
        A=A*3
        for i in range(length):
            point=0
            for j in range(mod+length):
                point +=A[i+j]
                ans=max(ans,base+point)
print(ans)

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

E=[]
color=["white" for _ in range(N)]
for i in range(N):
    if color[i]=="white":
        index,F=i,[]
        while 1:
            if color[index]=="white":
                color[index]="black"
                index=P[index]-1
                F.append(C[index])
            else:break
        E.append(F)

ans=-float("inf")
for A in E:
    length=len(A)
    if sum(A)<0:
        A=A*2
        for i in range(length):
            point=0
            for j in range(min(K,length)):
                point +=A[i+j]
                ans=max(ans,point)
    else:
        div,mod=divmod(K,length)
        base=(div-1)*sum(A)
        A=A*3
        for i in range(length):
            point=0
            for j in range(mod+length):
                point +=A[i+j]
                ans=max(ans,base+point)
print(ans)
# Original solution
n, k = list(map(int, input().split()))
Ps = list(map(int, input().split()))
Ps.insert(0,0)
Cs = list(map(int, input().split()))
Cs.insert(0,0)
Ls = [0] * (n + 1)  # 周期
As = [] # 回答候補

# 周期を見つける
for i in range(1,n + 1):
  count = 1
  temp = Ps[i]
  while temp != i:
    temp = Ps[temp]
    count += 1
  Ls[i] = count

# それぞれの最大値を見つける
for i in range(1, n + 1):
  ans = 0
  p = []  #途中経過集
  tempIndex = i
  tempSum = 0
  for j in range(Ls[i]):
    tempIndex = Ps[tempIndex]
    tempSum += Cs[tempIndex]
    p.append(tempSum)
  # print(f'p:{p}')
  # ansを求める
  if p[-1] <= 0:
    ans = max(p[:min(k,Ls[i])])
  else:
    q, r = divmod(k, Ls[i])
    # print(f'q,r,k,Ls[i]:{q}{r}{k}{Ls[i]}')
    start = q * p[-1]
    anss = [start]
    tempIndex = i
    tempSum = start
    for z in range(r):
      tempIndex = Ps[tempIndex]
      tempSum += Cs[tempIndex]
      anss.append(tempSum)
    ans = max(anss)
  As.append(ans)
print((max(As)))

# Optimized solution
n, k = list(map(int, input().split()))
Ps = list(map(int, input().split()))
Ps.insert(0,0)
Cs = list(map(int, input().split()))
Cs.insert(0,0)
Ls = [0] * (n + 1)  # 周期
As = [0] * (n) # 回答候補

# 周期を見つける
for i in range(1,n + 1):
  count = 1
  temp = Ps[i]
  while temp != i:
    temp = Ps[temp]
    count += 1
  Ls[i] = count

# それぞれの最大値を見つける
for i in range(1, n + 1):
  ans = 0
  p = [0] * Ls[i]  #途中経過集
  tempIndex = i
  tempSum = 0
  for j in range(Ls[i]):
    tempIndex = Ps[tempIndex]
    tempSum += Cs[tempIndex]
    p[j] = tempSum
  # print(f'p:{p}')
  # ansを求める
  if p[-1] <= 0:
    ans = max(p[:min(k,Ls[i])])
  else:
    q, r = divmod(k, Ls[i])
    # print(f'q,r,k,Ls[i]:{q}{r}{k}{Ls[i]}')
    start = (q - 1) * p[-1]
    anss = [0] * (r + Ls[i])
    anss.insert(0, start)
    tempIndex = i
    tempSum = start
    for z in range(r + Ls[i]): #rは高々Ls[i]、つまりn、つまり5 * (10**3)
      tempIndex = Ps[tempIndex]
      tempSum += Cs[tempIndex]
      anss[z + 1] = tempSum
    ans = max(anss)
  As[i-1] = ans
print((max(As)))
# Original solution
N,K = list(map(int, input().split()))
p = list(map(int, input().split()))
c = list(map(int, input().split()))

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

# Optimized solution
N,K = list(map(int, input().split()))
p = list(map(int, input().split()))
c = list(map(int, input().split()))
ans = -1* 10**9

for si in range(N):
  s = list()
  total = 0
  l = 0
  x = si
  while(1):
    x = p[x] - 1
    s.append(c[x])
    total += c[x]
    l += 1
    if x == si:
      break
  t = 0
  for j in range(l):
    t += s[j]
    now = t
    if j >= K:
      break
    if total > 0:
      e = (K-j-1)//l
      now += total * e
    ans = max(ans, now)

print(ans)
# Original solution
n,k = list(map(int,input().split()))
score = [0 for i in range(n)]
P = list(map(int,input().split()))
C = list(map(int,input().split()))
ans = -float('inf')
for i in range(n):
    start = i
    cur = i
    i_s_score = 0
    i_s_score_max = C[P[cur]-1]
    move_num = 0
    for j in range(n):
        cur = P[cur]-1
        i_s_score += C[cur]
        i_s_score_max = max(i_s_score, i_s_score_max)
        move_num += 1
        if cur == start:
            break
    if i_s_score <= 0:
        ans = max(ans, i_s_score_max)
    else:
        temp = i_s_score*(k//move_num)
        rest = k%move_num
        ans = max(ans, temp)
        i_s_score = temp
        for j in range(rest):
            cur = P[cur]-1
            i_s_score += C[cur]
            ans = max(ans, i_s_score)
print(ans)


# Optimized solution
n,k = list(map(int,input().split()))
P = list(map(int,input().split()))
C = list(map(int,input().split()))
ans = -10**100
for i in range(n):
    start = i
    cur = i
    i_s_score = 0
    i_s_score_max = C[P[cur]-1]
    move_num = 0
    for j in range(n):
        cur = P[cur]-1
        i_s_score += C[cur]
        i_s_score_max = max(i_s_score, i_s_score_max)
        move_num += 1
        if cur == start:
            break
    if i_s_score <= 0:
        ans = max(ans, i_s_score_max)
    else:
        temp = i_s_score*(k//move_num)
        if (k//move_num >= 1):
            temp_dash = i_s_score*(k//move_num-1)+i_s_score_max
            ans = max(ans, temp_dash)
        rest = k%move_num
        ans = max(ans, temp)
        i_s_score = temp
        for j in range(rest):
            cur = P[cur]-1
            i_s_score += C[cur]
            ans = max(ans, i_s_score)
print(ans)
# Original solution
N,K = list(map(int,input().split()))
P = list(map(int,input().split()))
C = list(map(int,input().split()))
##################################################################
max_point = -10000000000000
for i in range(N):
  point = 0
  now = i
  for j in range(K):
    next_place = P[now]-1
    point += C[next_place]
    max_point = max(point,max_point)
    now = next_place

print(max_point)

# Optimized solution
n,k = list(map(int, input().split()))
p = list([int(z)-1 for z in input().split()])
c = list(map(int, input().split()))

data = [[0 for i in range(n+1)] for j in range(n)]
loop = [10**10 for i in range(n)]
for i in range(n):
    j = i
    for t in range(1,n+1):
        j = p[j]
        data[i][t] += data[i][t-1] + c[j]
        if j == i:
            loop[i] = min(loop[i],t)

ans = -10**10
#print(data)
#print([data[i][loop[i]] for i in range(n)])

for i in range(n):
    for j in range(1,min(n,k)+1):
        if j > loop[i]:break
        if data[i][loop[i]] <= 0:
            ans = max(ans,data[i][j])
        else:
            ans = max(ans,data[i][loop[i]]*((k-j)//loop[i])+data[i][j])

print(ans)
# Original solution
N, K = [int(_) for _ in input().split()]
P = [int(_) - 1 for _ in input().split()]
C = [int(_) for _ in input().split()]


X = [False for _ in range(N)]

V = []
for i in range(N):
    if X[i]:
        continue
    t = i
    v = []
    while X[t] is False:
        X[t] = True
        v.append(C[t])
        t = P[t]
    V.append(tuple(v))

def f(v, K):
    if K == 0:
        return 0
    if max(v) < 0:
        return max(v)
    n = len(v)

    X = [0]
    for i in range(n):
        X.append(X[-1] + v[i])
    ans = -100000000000
    for i in range(n + 1):
        for j in range(i):
            if i - j > K:
                continue
            ans = max(ans, X[i] - X[j])
    return(ans)

ans = -100000000000
for v in V:
    n = len(v)
    if K > n:
        s = sum(v)
        if s > 0:
            x = s * (K // n) + f(v * 2, K % n)
            y = s * (K // n - 1) + f(v * 2, n)
            a = max(x, y)
        else:
            a = f(v * 2, n)
    else:
        a = f(v * 2, K)
    ans = max(a, ans)

print(ans)


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

def f(v, K):
    if K == 0:
        return 0
    if max(v) < 0:
        return max(v)

    n = len(v)
    X = [0]
    for i in range(n):
        X.append(X[-1] + v[i])

    ans = -(10 ** 10)
    for i in range(n + 1):
        for j in range(i):
            if i - j > K:
                continue
            ans = max(ans, X[i] - X[j])
    return(ans)

X = [False for _ in range(N)]
ans = -(10 ** 10)

for i in range(N):
    if X[i]:
        continue
    t = i
    v = []
    while X[t] is False:
        X[t] = True
        v.append(C[t])
        t = P[t]

    n = len(v)
    if K > n:
        s = sum(v)
        x = f(v * 2, n)
        if s > 0:
            a = s * (K // n - 1) + max(s + f(v * 2, K % n), x)
        else:
            a = x
    else:
        a = f(v * 2, K)
    ans = max(a, ans)

print(ans)