/**
 * Dont raise your voice, improve your argument.
 * --Desmond Tutu
 */

#include <bits/stdc++.h>
using namespace std;

const bool ready = [](){
    ios_base::sync_with_stdio(false); cin.tie(0);
    cout << fixed << setprecision(12);
    return true;
}();

const double PI = acos(-1);
using ll= long long;
#define int ll
#define all(v) (v).begin(), (v).end()
#define fori(n) for(int i=0; i<int(n); i++)

#define cini(i) int i; cin>>i;
#define cins(s) string s; cin>>s;
#define cind(d) double d; cin>>d;
#define cinai(a,n) vi a(n); fori(n) { cin>>a[i]; }
#define cinas(s,n) vs s(n); fori(n) { cin>>s[i]; }
#define cinad(a,n) vd a(n); fori(n) { cin>>a[i]; }

using pii= pair<int, int>;
using pdd= pair<double, double>;
using vd= vector<double>;
using vb= vector<bool>;
using vi= vector<int>;
using vvi= vector<vi>;
using vs= vector<string>;

#define endl "\n"

/* see https://cp-algorithms.com/data_structures/disjoint_set_union.html
 * Also known as union find structure. 
 * Note that the above link has some optimizations for faster combining of sets if needed. 
 */

struct Dsu {
    vector<int> p;
    vector<int> s;
/* initializes each (0..size-1) to single set */
    Dsu(int size) {
        p.resize(size);
        s.resize(size, 1);
        iota(p.begin(), p.end(), 0);
    }

/* makes v a single set, removes it from other set if contained there. */
    void make_set(int v) {
        p[v] = v;
    }

/* finds set representative for member v */
    int find_set(int v) {
        if (v == p[v])
            return v;
        return p[v] = find_set(p[v]);
    }

/* combines the sets of two members. 
 * Use the bigger set as param a for optimized performance.  */
    void union_sets(int a, int b) {
        a = find_set(a);
        b = find_set(b);
        if (a != b) {
            p[b] = a;
            s[a]+=s[b];
        }
    }
};

/* find components.
 * withing each component find max
 * max subarr of len k%complen.
 */
const int INF=1e9;
void solve() {
    cini(n);
    cini(k);

    vi p(n);
    for(int i=0; i<n; i++) {
        cin>>p[i];
        p[i]--;
    }

    cinai(c,n);
    Dsu dsu(n);
    vb vis(n);
    vi sum(n);
    vvi elems(n);

    for(int i=0; i<n; i++) {
        if(vis[i])
            continue;
        vis[i]=true;

        elems[i].push_back(c[i]);
        sum[i]=c[i];
        int v=p[i];
        while(v!=i) {
            elems[i].push_back(c[v]);
            sum[i]+=c[v];
            vis[v]=true;
            dsu.union_sets(i, v);
            v=p[v];
        }
    }

    /* We must choose min one element!
     * Then a number of full circle.
     * and a last segment of size max k-1.
     **/
    int ans=-INF;
    for(int i=0; i<n; i++) {
        if(dsu.find_set(i)!=i)
            continue;

        for(int j=0; j<dsu.s[i]; j++)   // double elems
            elems[i].push_back(elems[i][j]);

        /* now find biggest subarrays in elems[i] of max size lk
         * and k, brute force. */
        int lk=k%dsu.s[i];
        int maxLK=0;
        int maxK=-INF;
        for(int start=0; start<dsu.s[i]; start++) {
            int llsum=0;
            for(int kk=0; kk<min(k, dsu.s[i]); kk++) {
                llsum+=elems[i][start+kk];
                if(kk<lk)
                    maxLK=max(maxLK, llsum);

                maxK=max(maxK, llsum);
            }
        }

        
        int maxCircle=k/dsu.s[i];
        int lans=0;
        if(sum[i]>0) {
            lans=maxCircle*sum[i];
            lans+=maxLK;
            ans=max(ans, lans);
            lans=max(0LL, maxCircle-1)*sum[i];
            lans+=maxK;
            ans=max(ans, lans);
        } else {
            ans=max(ans, maxK);
        }
    }
    cout<<ans<<endl;

}

signed main() {
    solve();
}

// FIRST THINK, THEN CODE
// DO NOT JUMP BETWEEN PROBLEMS


Measured memory_bytes: 4036