N, K = map(int, input().split())
P = [0] + list(map(int, input().split()))
C = [0] + list(map(int, input().split()))

#マスに与えられたスコアが全部負だった場合には，その中で最もダメージの小さいマスを一つ踏んで終わる。
C_max = max(C[1:])
if C_max < 0:
    print(C_max)
    exit()


ans = 0

done = [False] * (N + 1) #チェック済みのマスはTrueにしていく。(loopはバラバラの構成員で構成されてるので。)

#loopの構成員をもらう。 -→ loopの中でマスaから始まりマスbで止まる操作をする場合の最大スコアを数える。
#の順番で解く。

for i in range(1, N + 1):
    if done[i]:
        continue
        #マスiがチェック済みの場合には何もせずiを次に進める。（continue）

    loop = [i] #ここにloopの構成員が記録される。iは最初から入れておく。
    now = P[i] #iから一歩進んだマスを起点として，loop構成員の記録を開始する。
    while now != i:
        loop.append(now)
        done[now] = True
        now = P[now]
        #今立っているマスがiでない場合は，loop構成員リストに記録して，doneをTrueにして，足を一歩進める。

    #print(loop)
    #loopの構成員のメモが完了！

    L = len(loop)
    S = sum(C[v] for v in loop) #loopを一周した時のスコア

    for a_ind in range(L):
        a = loop[a_ind]
        score_ab = -C[a]
        #例えば[3, 6, 4, 7]のloopがあった時，a = 3→6→4→7 と移っていきたいので，a_ind = 0→1→2...として，a =  loop[0]→loop[1]→loop[2]→loop[3]とする。bもまた然り。
        for b_ind in range(a_ind, a_ind + L):#aから数週してaに戻るプレイも可能なので，b == aとなる場合も含んでおかなければならない。
            dist_ab = b_ind - a_ind
            if dist_ab > K:
                break
            b = loop[b_ind % L]
            score_ab += C[b]

            max_score = score_ab + max(0, S) * ((K - dist_ab) // L)
            #スコアの最大値は，
            # S > 0の場合，[aからbまで移動した時のスコア] ＋ S * [可能な限りloopを周回する]　（周回した方が得なので）
            # S < 0の場合，[aからbまで移動した時のスコア]　（周回した方が損なので）
            #上の場合分けの切り替えを　max(0, S)　で行っている！地味にすごい！

            ans = max(ans, max_score)

print(ans) N, K = map(int, input().split()) N map(int, input().split()) map int input().split() ().split () input split K P = [0] + list(map(int, input().split())) P [0] + list(map(int, input().split())) [0] 0 list(map(int, input().split())) list map(int, input().split()) map int input().split() ().split () input split C = [0] + list(map(int, input().split())) C [0] + list(map(int, input().split())) [0] 0 list(map(int, input().split())) list map(int, input().split()) map int input().split() ().split () input split C_max = max(C[1:]) C_max max(C[1:]) max C[1:] C 1: 1 if C_max < 0:
    print(C_max)
    exit() C_max < 0 C_max 0 print(C_max) print C_max exit() exit ans = 0 ans 0 done = [False] * (N + 1) done [False] * (N + 1) [False] False N + 1 N 1 for i in range(1, N + 1):
    if done[i]:
        continue
        #マスiがチェック済みの場合には何もせずiを次に進める。（continue）

    loop = [i] #ここにloopの構成員が記録される。iは最初から入れておく。
    now = P[i] #iから一歩進んだマスを起点として，loop構成員の記録を開始する。
    while now != i:
        loop.append(now)
        done[now] = True
        now = P[now]
        #今立っているマスがiでない場合は，loop構成員リストに記録して，doneをTrueにして，足を一歩進める。

    #print(loop)
    #loopの構成員のメモが完了！

    L = len(loop)
    S = sum(C[v] for v in loop) #loopを一周した時のスコア

    for a_ind in range(L):
        a = loop[a_ind]
        score_ab = -C[a]
        #例えば[3, 6, 4, 7]のloopがあった時，a = 3→6→4→7 と移っていきたいので，a_ind = 0→1→2...として，a =  loop[0]→loop[1]→loop[2]→loop[3]とする。bもまた然り。
        for b_ind in range(a_ind, a_ind + L):#aから数週してaに戻るプレイも可能なので，b == aとなる場合も含んでおかなければならない。
            dist_ab = b_ind - a_ind
            if dist_ab > K:
                break
            b = loop[b_ind % L]
            score_ab += C[b]

            max_score = score_ab + max(0, S) * ((K - dist_ab) // L)
            #スコアの最大値は，
            # S > 0の場合，[aからbまで移動した時のスコア] ＋ S * [可能な限りloopを周回する]　（周回した方が得なので）
            # S < 0の場合，[aからbまで移動した時のスコア]　（周回した方が損なので）
            #上の場合分けの切り替えを　max(0, S)　で行っている！地味にすごい！

            ans = max(ans, max_score) i range(1, N + 1) range 1 N + 1 N 1 if done[i]:
        continue
        #マスiがチェック済みの場合には何もせずiを次に進める。（continue）

     done[i] done i continue loop = [i] loop [i] i now = P[i] now P[i] P i while now != i:
        loop.append(now)
        done[now] = True
        now = P[now]
        #今立っているマスがiでない場合は，loop構成員リストに記録して，doneをTrueにして，足を一歩進める。

    #print(loop)
    #loopの構成員のメモが完了！

     now != i now i loop.append(now) loop.append loop append now done[now] = True done[now] done now True now = P[now] now P[now] P now L = len(loop) L len(loop) len loop S = sum(C[v] for v in loop) S sum(C[v] for v in loop) sum C[v] C v for a_ind in range(L):
        a = loop[a_ind]
        score_ab = -C[a]
        #例えば[3, 6, 4, 7]のloopがあった時，a = 3→6→4→7 と移っていきたいので，a_ind = 0→1→2...として，a =  loop[0]→loop[1]→loop[2]→loop[3]とする。bもまた然り。
        for b_ind in range(a_ind, a_ind + L):#aから数週してaに戻るプレイも可能なので，b == aとなる場合も含んでおかなければならない。
            dist_ab = b_ind - a_ind
            if dist_ab > K:
                break
            b = loop[b_ind % L]
            score_ab += C[b]

            max_score = score_ab + max(0, S) * ((K - dist_ab) // L)
            #スコアの最大値は，
            # S > 0の場合，[aからbまで移動した時のスコア] ＋ S * [可能な限りloopを周回する]　（周回した方が得なので）
            # S < 0の場合，[aからbまで移動した時のスコア]　（周回した方が損なので）
            #上の場合分けの切り替えを　max(0, S)　で行っている！地味にすごい！

            ans = max(ans, max_score) a_ind range(L) range L a = loop[a_ind] a loop[a_ind] loop a_ind score_ab = -C[a] score_ab -C[a] C[a] C a for b_ind in range(a_ind, a_ind + L):#aから数週してaに戻るプレイも可能なので，b == aとなる場合も含んでおかなければならない。
            dist_ab = b_ind - a_ind
            if dist_ab > K:
                break
            b = loop[b_ind % L]
            score_ab += C[b]

            max_score = score_ab + max(0, S) * ((K - dist_ab) // L)
            #スコアの最大値は，
            # S > 0の場合，[aからbまで移動した時のスコア] ＋ S * [可能な限りloopを周回する]　（周回した方が得なので）
            # S < 0の場合，[aからbまで移動した時のスコア]　（周回した方が損なので）
            #上の場合分けの切り替えを　max(0, S)　で行っている！地味にすごい！

            ans = max(ans, max_score) b_ind range(a_ind, a_ind + L) range a_ind a_ind + L a_ind L dist_ab = b_ind - a_ind dist_ab b_ind - a_ind b_ind a_ind if dist_ab > K:
                break
             dist_ab > K dist_ab K break b = loop[b_ind % L] b loop[b_ind % L] loop b_ind % L b_ind L score_ab += C[b] score_ab C[b] C b max_score = score_ab + max(0, S) * ((K - dist_ab) // L) max_score score_ab + max(0, S) * ((K - dist_ab) // L) score_ab max(0, S) * ((K - dist_ab) // L) max(0, S) max 0 S (K - dist_ab) // L K - dist_ab K dist_ab L ans = max(ans, max_score) ans max(ans, max_score) max ans max_score print(ans) print ans score_ab = -C[a] -C[a] score_ab score_ab += C[b] C[b] score_ab loop = [i] [i] loop now = P[i] P[i] now ans = max(ans, max_score) max(ans, max_score) ans P = [0] + list(map(int, input().split())) [0] + list(map(int, input().split())) P done = [False] * (N + 1) [False] * (N + 1) done C_max = max(C[1:]) max(C[1:]) C_max ans = 0 0 ans dist_ab = b_ind - a_ind b_ind - a_ind dist_ab S = sum(C[v] for v in loop) sum(C[v] for v in loop) S now = P[now] P[now] now b = loop[b_ind % L] loop[b_ind % L] b max_score = score_ab + max(0, S) * ((K - dist_ab) // L) score_ab + max(0, S) * ((K - dist_ab) // L) max_score K = map(int, input().split()) map(int, input().split()) K L = len(loop) len(loop) L a = loop[a_ind] loop[a_ind] a C = [0] + list(map(int, input().split())) [0] + list(map(int, input().split())) C N, K = map(int, input().split()) map(int, input().split()) N
N, K = map(int, input().split())
P = [0] + list(map(int, input().split()))
C = [0] + list(map(int, input().split()))

#マスに与えられたスコアが全部負だった場合には，その中で最もダメージの小さいマスを一つ踏んで終わる。
C_max = max(C[1:])
if C_max < 0:
    print(C_max)
    exit()


ans = 0

done = [False] * (N + 1) #チェック済みのマスはTrueにしていく。(loopはバラバラの構成員で構成されてるので。)

#loopの構成員をもらう。 -→ loopの中でマスaから始まりマスbで止まる操作をする場合の最大スコアを数える。
#の順番で解く。

for i in range(1, N + 1):
    if done[i]:
        continue
        #マスiがチェック済みの場合には何もせずiを次に進める。（continue）

    loop = [i] #ここにloopの構成員が記録される。iは最初から入れておく。
    now = P[i] #iから一歩進んだマスを起点として，loop構成員の記録を開始する。
    while now != i:
        loop.append(now)
        done[now] = True
        now = P[now]
        #今立っているマスがiでない場合は，loop構成員リストに記録して，doneをTrueにして，足を一歩進める。

    #print(loop)
    #loopの構成員のメモが完了！

    L = len(loop)
    S = sum(C[v] for v in loop) #loopを一周した時のスコア

    for a_ind in range(L):
        a = loop[a_ind]
        score_ab = -C[a]
        #例えば[3, 6, 4, 7]のloopがあった時，a = 3→6→4→7 と移っていきたいので，a_ind = 0→1→2...として，a =  loop[0]→loop[1]→loop[2]→loop[3]とする。bもまた然り。
        for b_ind in range(a_ind, a_ind + L):#aから数週してaに戻るプレイも可能なので，b == aとなる場合も含んでおかなければならない。
            dist_ab = b_ind - a_ind
            if dist_ab > K:
                break
            b = loop[b_ind % L]
            score_ab += C[b]

            max_score = score_ab + max(0, S) * ((K - dist_ab) // L)
            #スコアの最大値は，
            # S > 0の場合，[aからbまで移動した時のスコア] ＋ S * [可能な限りloopを周回する]　（周回した方が得なので）
            # S < 0の場合，[aからbまで移動した時のスコア]　（周回した方が損なので）
            #上の場合分けの切り替えを　max(0, S)　で行っている！地味にすごい！

            ans = max(ans, max_score)

print(ans)