#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#pragma GCC diagnostic ignored "-Wmisleading-indentation"
#pragma GCC diagnostic ignored "-Wunused-variable"

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp> 
using namespace __gnu_pbds;
using namespace std;
using namespace std::chrono; 

typedef long long ll;
typedef uint64_t ull;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef set<ll> sl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
template<class key_type, class cont = vl, class comp = less<key_type>>
using p_queue = priority_queue<key_type, cont, comp>;
template<class key_type, class comp = less<key_type>>
using my_set = tree<key_type, null_type, comp, rb_tree_tag, tree_order_statistics_node_update>;
template<class key_type, class value_type, class comp = less<key_type>>
using my_map = tree<key_type, value_type, comp, rb_tree_tag, tree_order_statistics_node_update>;

const ll INF = (ll)9e18;
const ll mod1 = 998244353;
const ll mod2 = 1000000007; //10^9 + 7
#define sz(v) ll((v).size())
#define all(v) v.begin(), v.end()
#define pub push_back
#define pob pop_back
#define puf push_front
#define pof pop_front
#define mp make_pair
#define mt make_tuple
#define rep1(i, a, b, change) for (ll i = a; i <= b; i += change)
#define rep1r(i, a, b, change) for (ll i = a; i >= b; i -= change)
#define rep(i, a, b) for (ll i = a; i <= b; i++)
#define repr(i, a, b) for (ll i = a; i >= b; i--)
#define SQ(a) ll(a) * (a)
#define nl cout << '\n'
#define yes cout << "YES\n"
#define no cout<< "NO\n"
#define max3(a, b, c) max(a, max(b, c))
#define max4(a, b, c, d) max(a, max3(b, c, d))
#define max5(a, b, c, d, e) max(a, max4(b, c, d, e))
#define min3(a, b, c) min(a, min(b, c))
#define min4(a, b, c, d) min(a, min3(b, c, d))
#define min5(a, b, c, d, e) min(a, min4(b, c, d, e))
#define out2(a, b) cout << a << ' ' << b << '\n'
#define in2(a, b) cin >> a >> b
#define out3(a, b, c) cout << a << ' ' << b << ' ' << c << '\n'
#define in3(a, b, c) cin >> a >> b >> c
#define out4(a, b, c, d) cout << a << ' ' << b << ' ' << c <<  ' ' << d << '\n'
#define in4(a, b, c, d) cin >> a >> b >> c >> d
#define google(x, y) cout << "Case #" << x << ": " << y << '\n'
#define clk_start auto start = steady_clock::now()
#define clk_finish auto finish = steady_clock::now()
#define clk_dur duration_cast<milliseconds>(finish - start).count()

template<typename T>
ostream& operator<<(ostream& stream, const vector<T>& vec)
{
    ll n = vec.size();
	for (ll i = 0; i < n; i++)
	{
		stream << vec[i] << ' ';
	}
	stream << '\n';
	return stream;
}

template<class T>
istream& operator>>(istream& stream, vector<T>& vec)
{
    ll n = vec.size();
	for (ll j = 1; j < n; j++)
	{
		stream >> vec[j];
	}
	return stream;
}

istream& operator>>(istream& stream, pll& p)
{
	stream >> p.first >> p.second;
	return stream;
}

//all function prototypes
ll ilog(ll n, ll base);
ll power(ll, ll);
void InverseofNumbers(ll, ll);
void InverseofFactorial(ll, ll);
void factorialmod(ll, ll);
ll ncrmod(ll n, ll r, ll p);
ll ncr(ll n, ll r);
tuple<ll, ll, ll> euclid(ll a, ll b);
ll modInverse(ll n, ll p);
ll phi(ll n);
bool checkprime(ll p);
ll power_mod(ll x, ll y, ll p);
void prime_generator(ll n);
void sieve(ll n);
vector<ll> getFactorization(ll x);
void naive_subset_search(ll k, vl& arr);
void radix_sort(vector<ll>& arr);

//all function definitions
ll ilog(ll n, ll base)
{
	ll prod = base;
	ll p = 0;
	while (1)
	{
		if (n < prod)
		{
			return p;
		}
		prod *= base;
		p++;
	}
}

ll power(ll x, ll y)
{
	ll res = 1;
	while (y > 0)
	{
		if (y & 1)
			res = (res * x);
		y = y >> 1;
		x = (x * x);
	}
	return res;
}

vl numinverse;
void InverseofNumbers(ll n, ll p) //p is prime
{ 
    numinverse.resize(n + 1);
    numinverse[0] = numinverse[1] = 1; 
    for (ll i = 2; i <= n; i++) 
        numinverse[i] = numinverse[p % i] * (p - p / i) % p; 
} 

vl factorial_inverse;
void InverseofFactorial(ll n, ll p) 
{ 
    factorial_inverse.resize(n + 1);
    factorial_inverse[0] = factorial_inverse[1] = 1; 
    for (int i = 2; i <= n; i++) 
        factorial_inverse[i] = (numinverse[i] * factorial_inverse[i - 1]) % p; 
}

vl fact; 
//fact[i] = factorial(i) % p //O(n)
void factorialmod(ll n, ll p)
{
	fact.resize(n + 1);
    ll ans = 1;
    rep(i, 0, n)
    {
        fact[i] = ans;
        ans = (ans * (i + 1)) % p;
    }
}

ll ncrmod(ll n, ll r, ll p)
{ 
    ll ans = ((fact[n] * factorial_inverse[r]) 
              % p * factorial_inverse[n - r]) 
             % p; 
    return ans; 
}

ll ncr(ll n, ll r)
{
    if (n < r)
        return 0;
	ll res = 1;
	if (r > n - r)
		r = n - r;
	rep(i, 0, r-1)
	{
		res *= (n - i);
		res /= (i + 1);
	}
	return res;
}

tuple<ll, ll, ll> euclid(ll a, ll b)
{
	ll d1, x1, y1;
	if (b == 0)
		return { a, 1, 0 };
	else
	{
		tie(d1, x1, y1) = euclid(b, a % b);
	}
	ll d = d1, x = y1, y = x1 - a / b * y1;
	return { d, x, y };
}

ll modInverse(ll n, ll p)
{
	return power_mod(n, p - 2, p);
}

ll phi(ll n) {
	ll result = n;
	for (ll i = 2; i * i <= n; i++) {
		if (n % i == 0) {
			while (n % i == 0)
				n /= i;
			result -= result / i;
		}
	}
	if (n > 1)
		result -= result / n;
	return result;
}

bool checkprime(ll p)
{
    bool ans = true;
    for (ll i = 2; i * i <= p; i++)
    {
        if (p % i) continue;
        ans = false;
        break;
    }
    return ans;
}

ll power_mod(ll x, ll y, ll p)
{
	if (checkprime(p)) y %= (p - 1);
	ll res = 1;
	x = x % p;
	while (y > 0)
	{
		if (y & 1)
			res = (res * x) % p;
		y = y >> 1;
		x = (x * x) % p;
	}
	return res;
}

vector<bool> is_prime;
vector<ll> primes;
void prime_generator(ll n)
{
	is_prime = vector<bool>(n + 1, false);
	vector<bool> a(n + 1, true);
	for (ll i = 2; i * i <= n; i++)
	{
		if (a[i])
		{
			for (ll j = i * i; j <= n; j += i)
			{
				a[j] = false;
			}
		}
	}
	for (ll i = 2; i <= n; i++)
	{
		if (a[i])
		{
			is_prime[i] = true;
			primes.pub(a[i]);
		}
	}
}

vector<ll> spf;
void sieve(ll n)
{
	spf = vl(n + 1);
	spf[1] = 1;
	for (ll i = 2; i <= n; i++)
		spf[i] = i;
	for (ll i = 4; i <= n; i += 2)
		spf[i] = 2;

	for (ll i = 3; i * i <= n; i++)
	{
		if (spf[i] == i)
		{
			for (ll j = i * i; j <= n; j += i)
				if (spf[j] == j)
					spf[j] = i;
		}
	}
}

vector<ll> getFactorization(ll x)
{
	vector<ll> ret;
	while (x != 1)
	{
		ret.push_back(spf[x]);
		x = x / spf[x];
	}
	return ret;
}

vl subset;
void naive_subset_search(ll k, vl& arr)
{
	if (k == sz(arr))
	{
		//Process subset
		//for eg we can do cout << subset
	}
	else
	{
		naive_subset_search(k + 1, arr);
		subset.pub(arr[k]);
		naive_subset_search(k + 1, arr);
		subset.pob();
	}
}

void radix_sort(vector<ll>& arr)
{
	ll d = 0;
	for (const auto& i : arr)
	{
		d = max(d, ilog(i, 10) + 1);
	}
	ll n = arr.size();
	vector<queue<ll> > digits(10);
	ll prod = 10;
	vector<ll> tmp = arr;
	while (d--)
	{
		for (ll i = 0; i < n; i++)
		{
			digits[tmp[i] % 10].push(arr[i]);
		}
		ll index = 0;
		for (ll i = 0; i < 10; i++)
		{
			while (!digits[i].empty())
			{
				arr[index] = digits[i].front();
				tmp[index] = arr[index] / prod;
				digits[i].pop();
				index++;
			}
		}
		prod *= 10;
	}
}

ll tc = 1;
void solve();

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	ll t = 1;
	//cin >> t;
	//clk_start;
	for (tc = 1; tc <= t; tc++) solve();
	//clk_finish;
	//cout << clk_dur << '\n';
	return 0;
}

void solve()
{
	ll n, k;
    in2(n, k);
    vl p(n+1), c(n+1);
    in2(p, c);
    vl pref;
    ll ans = *max_element(begin(c)+1, end(c));
    rep(i, 1, n)
    {
        ll j = p[i];
        pref.push_back(0);
        pref.push_back(pref.back() + c[j]);
        while (p[j] != p[i])
        {
            j = p[j];
            pref.push_back(pref.back() + c[j]);
        }
        ll n1 = sz(pref) - 1, tmp; //n1 is the max index of pref
        if (k <= n1)
        {
            tmp = *max_element(begin(pref) + 1, begin(pref) + (k+1));
            ans = max(ans, tmp);
        }
        else
        {   
            tmp = *max_element(begin(pref)+1, end(pref));
            ll rem = k % n1;
            if (rem == 0) rem += n1;
            ll tmp1 = *max_element(begin(pref)+1, begin(pref)+(rem+1));
            if (pref.back() <= 0)
            {
                ans = max(ans, tmp);
            }
            else
            {
                ll b = pref.back();
                tmp1 += ((ll)ceil(k / double(n1)) - 1) * b;
                ans = max3(ans, tmp, tmp1);
            }
        }
        pref.clear();
    }
    cout << ans << '\n';
}

//#pragma GCC diagnostic pop

Measured memory_bytes: 3904