Buggy python submission (verdict: Time Limit Exceeded):
N, K = [int(x) for x in input().split()]
P = [0] + [int(x) for x in input().split()]
C = [0] + [int(x) for x in input().split()]

max_score = max(C[1:])
for init in range(1, N + 1):   # 初めの場所をinitとする
    score = [0]  # k回移動後のスコア
    i = init
    for k in range(1, K + 1):
        i = P[i]  # k回移動後に着くところ
        score.append(score[-1] + C[i])
        max_score = max(max_score, score[k])
        if i == init:  # ループ検出
            loop_score = score[-1]
            loop_len = k
            if loop_score > 0:
                max_score = max(max_score, max(score[j] + loop_score * ((K - j) // loop_len) for j in range(1, loop_len + 1)))
            break

print(max_score)

Fixed submission:

from collections import defaultdict
INF = float('inf')
N, K = [int(x) for x in input().split()]
P = [0] + [int(x) for x in input().split()]
C = [0] + [int(x) for x in input().split()]

max_score = -INF
for init in range(1, N + 1):   # 初めの場所をiとする
    score = defaultdict(int)  # int/bool/list....
    # visited = defaultdict(init)  # int/bool/list....
    visited = [-1] * (N + 1)
    visited[init] = 0  # 何回移動後に着いたか？
    i = init
    max_init = -INF
    for k in range(1, K + 1):
        prev = i
        i = P[i]    # k回移動後に着くところ



        # if not visited[i]:
        if visited[i] < 0:  # まだ訪れてなかった
            visited[i] = k
            score[i] = score[prev] + C[i]
            max_init = max(max_init, score[i])
            continue

        loop_score = (score[prev] + C[i]) - score[i]
        loop_len = k - visited[i]

        score[i] = score[prev] + C[i]
        max_init = max(max_init, score[i])

        if k == K:
            break # これ以上移動できない

        start = i   # ループを開始するノード
        loop_num = (K - k) // loop_len # ループをあと何回回れるか
        loop_rem = (K - k) % loop_len

        if loop_rem == 0:
            loop_num -= 1
            loop_rem = loop_len

        jj = start
        temp = 0
        temp_max = 0
        for l in range(loop_rem):
            jj = P[jj]
            temp += C[jj]
            temp_max = max(temp_max, temp)

        # loop_max = temp_max + max(loop_num * loop_score, 0)
        loop_max = temp_max + loop_num * loop_score
        max_init = max(max_init, score[start] + loop_max)
        break

    max_score = max(max_score, max_init)

if max_score == -INF:
    max_score = max(C[1:])

print(max_score)

Buggy python submission (verdict: Time Limit Exceeded):
from collections import defaultdict
INF = float('inf')
N, K = [int(x) for x in input().split()]
P = [0] + [int(x) for x in input().split()]
C = [0] + [int(x) for x in input().split()]

max_score = -INF
for init in range(1, N + 1):   # 初めの場所をiとする
    score = defaultdict(int)  # int/bool/list....
    visited = defaultdict(bool)  # int/bool/list....
    visited[init] = True
    i = init
    max_init = -INF
    for k in range(1, K + 1):
        prev = i
        i = P[i]    # k回移動後に着くところ

        score[i] = score[prev] + C[i]
        max_init = max(max_init, score[i])

        if visited[i]:
            if k == K:
                break # これ以上移動できない
            start = i   # ループを開始するノード
            loop_score = 0
            loop_len = 0
            # ループを探す
            jj = start
            while P[jj] != start:
                jj = P[jj]
                loop_score += C[jj]
                loop_len += 1
            loop_score += C[start]
            loop_len += 1

            loop_num = (K - k) // loop_len # ループをあと何回回れるか
            loop_rem = (K - k) % loop_len

            if loop_rem == 0:
                loop_num -= 1
                loop_rem = loop_len

            jj = start
            temp = 0
            temp_max = 0
            for l in range(loop_rem):
                jj = P[jj]
                temp += C[jj]
                temp_max = max(temp_max, temp)

            loop_max = temp_max + max(loop_num * loop_score, 0)
            max_init = max(max_init, score[start] + loop_max)
            break

    max_score = max(max_score, max_init)

if max_score == -INF:
    max_score = max(C[1:])

print(max_score)

Fixed submission:

from collections import defaultdict
INF = float('inf')
N, K = [int(x) for x in input().split()]
P = [0] + [int(x) for x in input().split()]
C = [0] + [int(x) for x in input().split()]

max_score = -INF
for init in range(1, N + 1):   # 初めの場所をiとする
    score = defaultdict(int)  # int/bool/list....
    # visited = defaultdict(init)  # int/bool/list....
    visited = [-1] * (N + 1)
    visited[init] = 0  # 何回移動後に着いたか？
    i = init
    max_init = -INF
    for k in range(1, K + 1):
        prev = i
        i = P[i]    # k回移動後に着くところ



        # if not visited[i]:
        if visited[i] < 0:  # まだ訪れてなかった
            visited[i] = k
            score[i] = score[prev] + C[i]
            max_init = max(max_init, score[i])
            continue

        loop_score = (score[prev] + C[i]) - score[i]
        loop_len = k - visited[i]

        score[i] = score[prev] + C[i]
        max_init = max(max_init, score[i])

        if k == K:
            break # これ以上移動できない

        start = i   # ループを開始するノード
        loop_num = (K - k) // loop_len # ループをあと何回回れるか
        loop_rem = (K - k) % loop_len

        if loop_rem == 0:
            loop_num -= 1
            loop_rem = loop_len

        jj = start
        temp = 0
        temp_max = 0
        for l in range(loop_rem):
            jj = P[jj]
            temp += C[jj]
            temp_max = max(temp_max, temp)

        # loop_max = temp_max + max(loop_num * loop_score, 0)
        loop_max = temp_max + loop_num * loop_score
        max_init = max(max_init, score[start] + loop_max)
        break

    max_score = max(max_score, max_init)

if max_score == -INF:
    max_score = max(C[1:])

print(max_score)