Problem:
Score : 400 points

Problem Statement

Takahashi will play a game using a piece on an array of squares numbered 1, 2, \cdots, N. Square i has an integer C_i written on it. Also, he is given a permutation of 1, 2, \cdots, N: P_1, P_2, \cdots, P_N.

Now, he will choose one square and place the piece on that square. Then, he will make the following move some number of times between 1 and K (inclusive):

In one move, if the piece is now on Square i (1 \leq i \leq N), move it to Square P_i. Here, his score increases by C_{P_i}.

Help him by finding the maximum possible score at the end of the game. (The score is 0 at the beginning of the game.)

Constraints

2 \leq N \leq 5000

1 \leq K \leq 10^9

1 \leq P_i \leq N

P_i \neq i

P_1, P_2, \cdots, P_N are all different.

-10^9 \leq C_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N K
P_1 P_2 \cdots P_N
C_1 C_2 \cdots C_N

Output

Print the maximum possible score at the end of the game.

Sample Input 1

5 2
2 4 5 1 3
3 4 -10 -8 8

Sample Output 1

8

When we start at some square of our choice and make at most two moves, we have the following options:

If we start at Square 1, making one move sends the piece to Square 2, after which the score is 4. Making another move sends the piece to Square 4, after which the score is 4 + (-8) = -4.

If we start at Square 2, making one move sends the piece to Square 4, after which the score is -8. Making another move sends the piece to Square 1, after which the score is -8 + 3 = -5.

If we start at Square 3, making one move sends the piece to Square 5, after which the score is 8. Making another move sends the piece to Square 3, after which the score is 8 + (-10) = -2.

If we start at Square 4, making one move sends the piece to Square 1, after which the score is 3. Making another move sends the piece to Square 2, after which the score is 3 + 4 = 7.

If we start at Square 5, making one move sends the piece to Square 3, after which the score is -10. Making another move sends the piece to Square 5, after which the score is -10 + 8 = -2.

The maximum score achieved is 8.

Sample Input 2

2 3
2 1
10 -7

Sample Output 2

13

Sample Input 3

3 3
3 1 2
-1000 -2000 -3000

Sample Output 3

-1000

We have to make at least one move.

Sample Input 4

10 58
9 1 6 7 8 4 3 2 10 5
695279662 988782657 -119067776 382975538 -151885171 -177220596 -169777795 37619092 389386780 980092719

Sample Output 4

29507023469

The absolute value of the answer may be enormous.

Solution in Common Lisp (SBCL 2.0.3) (judge verdict: Wrong Answer)

(in-package :cl-user)
(eval-when (:compile-toplevel :load-toplevel :execute)
  (sb-int:defconstant-eqx opt
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0))
    #'equal)
  #+swank (ql:quickload '(:cl-debug-print :fiveam) :silent t)
  #-swank (set-dispatch-macro-character
           #\# #\> (lambda (s c p) (declare (ignore c p)) `(values ,(read s nil nil t)))))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)

(defmacro define-int-types (&rest bits)
  `(progn
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "UINT~A" b)) () '(unsigned-byte ,b))) bits)
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "INT~A" b)) () '(signed-byte ,b))) bits)))
(define-int-types 2 4 7 8 15 16 31 32 62 63 64)

(defconstant +mod+ 1000000007)

(defmacro dbg (&rest forms)
  #+swank (if (= (length forms) 1)
              `(format *error-output* "~A => ~A~%" ',(car forms) ,(car forms))
              `(format *error-output* "~A => ~A~%" ',forms `(,,@forms)))
  #-swank (declare (ignore forms)))

(declaim (inline println))
(defun println (obj &optional (stream *standard-output*))
  (let ((*read-default-float-format* 'double-float))
    (prog1 (princ obj stream) (terpri stream))))

;; BEGIN_INSERTED_CONTENTS
(defpackage :cp/read-fixnum
  (:use :cl)
  (:export #:read-fixnum))
(in-package :cp/read-fixnum)

(declaim (ftype (function * (values fixnum &optional)) read-fixnum))
(defun read-fixnum (&optional (in *standard-input*))
  "NOTE: cannot read -2^62"
  (macrolet ((%read-byte ()
               `(the (unsigned-byte 8)
                     #+swank (char-code (read-char in nil #\Nul))
                     #-swank (sb-impl::ansi-stream-read-byte in nil #.(char-code #\Nul) nil))))
    (let* ((minus nil)
           (result (loop (let ((byte (%read-byte)))
                           (cond ((<= 48 byte 57)
                                  (return (- byte 48)))
                                 ((zerop byte) ; #\Nul
                                  (error "Read EOF or #\Nul."))
                                 ((= byte #.(char-code #\-))
                                  (setq minus t)))))))
      (declare ((integer 0 #.most-positive-fixnum) result))
      (loop
        (let* ((byte (%read-byte)))
          (if (<= 48 byte 57)
              (setq result (+ (- byte 48)
                              (* 10 (the (integer 0 #.(floor most-positive-fixnum 10))
                                         result))))
              (return (if minus (- result) result))))))))

;;;
;;; Some operations on symmetric group
;;;

(defpackage :cp/symmetric-group
  (:use :cl)
  (:export #:decompose-to-cycles #:perm* #:perm-inverse #:make-identity-permutation))
(in-package :cp/symmetric-group)

;; NOTE: Here the underlying set is 0-based: {0, 1, 2, ..., N-1}

(declaim (inline decompose-to-cycles))
(defun decompose-to-cycles (permutation)
  "Returns the list of all the cyclic permutations in PERMUTATION and returns
its parity as the second value. (Actually the second value is the distance to
the identity permutation, (0, 1, ..., N-1), w.r.t. swapping.)"
  (declare (vector permutation))
  (let* ((n (length permutation))
         result
         (visited (make-array n :element-type 'bit :initial-element 0))
         (sign 0))
    (declare ((integer 0 #.most-positive-fixnum) sign))
    (dotimes (init n)
      (when (zerop (sbit visited init))
        (push (loop for x = init then (aref permutation x)
                    until (= (sbit visited x) 1)
                    collect x
                    do (setf (sbit visited x) 1)
                       (incf sign))
              result)
        (decf sign)))
    (values result sign)))

(declaim (inline perm*))
(defun perm* (perm1 perm2)
  "Composes two permutations. (Actually the arguments doesn't need to be
permutations. This is just a composition of two maps.)"
  (let* ((n (length perm1))
         (result (make-array n :element-type 'fixnum)))
    (dotimes (i n)
      (setf (aref result i) (aref perm2 (aref perm1 i))))
    result))

(declaim (inline perm-inverse))
(defun perm-inverse (perm)
  (let* ((n (length perm))
         (result (make-array n :element-type 'fixnum)))
    (dotimes (i n)
      (setf (aref result (aref perm i)) i))
    result))

(declaim (inline make-identity-permutation))
(defun make-identity-permutation (size)
  "Returns #(0 1 2 ... SIZE-1)."
  (declare ((integer 0 #.most-positive-fixnum) size))
  (let ((result (make-array size :element-type 'fixnum)))
    (dotimes (i size)
      (setf (aref result i) i))
    result))

;;;;
;;;; Sliding window optimum
;;;;

(defpackage :cp/sliding-window
  (:use :cl)
  (:export #:calc-window-opt #:sliding-window #:make-sliding-window
           #:swindow-extend #:swindow-shrink #:swindow-get #:swindow-empty-p #:swindow-reinitialize))
(in-package :cp/sliding-window)

;;;
;;; For window of fixed width
;;;

(declaim (inline calc-window-opt))
(defun calc-window-opt (vector width order)
  "Computes all the minima (or maxima) of the subsequences of the given width,
VECTOR[i, i+WIDTH), in O(n). Returns a vector, whose i-th element is the
minimum (or maximum) of the subsequence beginning with the index i.

ORDER := strict order (#'< corresponds to slide min. and #'> to slide max.)"
  (declare (vector vector)
           ((integer 1 #.most-positive-fixnum) width))
  (let* ((n (length vector))
         (deq (make-array n :element-type '(integer 0 #.most-positive-fixnum)))
         (front-pos 0)
         (end-pos -1)
         (l 0)
         (r 0)
         (res (make-array (+ 1 (- n width)) :element-type (array-element-type vector))))
    (declare ((integer -1 #.most-positive-fixnum) front-pos end-pos l r))
    (assert (<= width n))
    (labels ((push-back (x)
               (incf end-pos)
               (setf (aref deq end-pos) x))
             (pop-back () (decf end-pos))
             (pop-front () (incf front-pos))
             (peek-back () (aref deq end-pos))
             (peek-front () (aref deq front-pos))
             (extend ()
               (loop while (and (<= front-pos end-pos)
                                (not (funcall order
                                              (aref vector (peek-back))
                                              (aref vector r))))
                     do (pop-back))
               (push-back r)
               (incf r))
             (shrink ()
               (when (= (aref deq front-pos) l)
                 (pop-front))
               (incf l)))
      (declare (inline push-back pop-back pop-front peek-back peek-front))
      (loop for i below width
            do (extend))
      (loop for i from width below n
            do (setf (aref res (- i width))
                     (aref vector (peek-front)))
               (extend)
               (shrink)
            finally (setf (aref res (- i width))
                          (aref vector (peek-front))))
      res)))

;;;
;;; For window of variable width
;;;

(defstruct (sliding-window (:constructor make-sliding-window
                               (size &aux
                                     (times (make-array size :element-type 'fixnum))
                                     (values (make-array size :element-type 'fixnum))))
                           (:conc-name %swindow-)
                           (:copier nil)
                           (:predicate nil))
  (front-pos 0 :type (integer 0 #.most-positive-fixnum))
  (end-pos -1 :type (integer -1 #.most-positive-fixnum))
  (times nil :type (simple-array fixnum (*)))
  (values nil :type (simple-array fixnum (*))))

(defun %swindow-push-back (time value sw)
  (let ((new-end-pos (+ 1 (%swindow-end-pos sw))))
    (setf (aref (%swindow-times sw) new-end-pos) time
          (aref (%swindow-values sw) new-end-pos) value
          (%swindow-end-pos sw) new-end-pos)))

(defun %swindow-pop-back (sw)
  (decf (%swindow-end-pos sw)))

(defun %swindow-pop-front (sw)
  (incf (%swindow-front-pos sw)))

(declaim (inline swindow-extend))
(defun swindow-extend (time value sw order)
  "ORDER := #'< => minimum
ORDER := #'> => maximum"
  (let ((values (%swindow-values sw)))
    (loop while (and (<= (%swindow-front-pos sw) (%swindow-end-pos sw))
                     (not (funcall order
                                   (aref values (%swindow-end-pos sw))
                                   value)))
          do (%swindow-pop-back sw))
    (%swindow-push-back time value sw)))

(declaim (inline swindow-shrink))
(defun swindow-shrink (time sw)
  "Advance the left end of the time range to TIME (inclusive)."
  (let ((times (%swindow-times sw)))
    (loop while (and (<= (%swindow-front-pos sw) (%swindow-end-pos sw))
                     (< (aref times (%swindow-front-pos sw)) time))
          do (%swindow-pop-front sw))))

(declaim (inline swindow-empty-p))
(defun swindow-empty-p (sw)
  (> (%swindow-front-pos sw) (%swindow-end-pos sw)))

(declaim (inline swindow-get-opt))
(defun swindow-get (sw)
  (assert (not (swindow-empty-p sw)))
  (let ((front-pos (%swindow-front-pos sw)))
    (aref (%swindow-values sw) front-pos)))

(declaim (inline swindow-reinitialize))
(defun swindow-reinitialize (sw)
  (setf (%swindow-front-pos sw) 0
        (%swindow-end-pos sw) -1))

(defpackage :cp/modify-macro
  (:use :cl)
  (:export #:minf #:maxf #:mulf #:divf #:iorf #:xorf #:andf))
(in-package :cp/modify-macro)

(macrolet ((def (name fname)
             `(define-modify-macro ,name (new-value) ,fname)))
  (def minf min)
  (def maxf max)
  (def mulf *)
  (def divf /)
  (def iorf logior)
  (def xorf logxor)
  (def andf logand))

;; BEGIN_USE_PACKAGE
(eval-when (:compile-toplevel :load-toplevel :execute)
  (use-package :cp/modify-macro :cl-user))
(eval-when (:compile-toplevel :load-toplevel :execute)
  (use-package :cp/sliding-window :cl-user))
(eval-when (:compile-toplevel :load-toplevel :execute)
  (use-package :cp/symmetric-group :cl-user))
(eval-when (:compile-toplevel :load-toplevel :execute)
  (use-package :cp/read-fixnum :cl-user))
(in-package :cl-user)

;;;
;;; Body
;;;

(defun main ()
  (let* ((n (read))
         (k (read))
         (ps (make-array n :element-type 'fixnum :initial-element 0))
         (cs (make-array n :element-type 'fixnum :initial-element 0))
         (res most-negative-fixnum))
    (dotimes (i n)
      (setf (aref ps i) (- (read-fixnum) 1)))
    (dotimes (i n)
      (setf (aref cs i) (read-fixnum)))
    (let ((cycles (decompose-to-cycles ps)))
      (dolist (cycle cycles)
        (let* ((len (length cycle))
               (scores (loop for p in cycle collect (aref cs p)))
               (lap-sum (reduce #'+ scores))
               (scores (concatenate '(simple-array fixnum (*)) scores scores))
               (cumuls (make-array (+ (length scores) 1) :element-type 'fixnum :initial-element 0)))
          (dotimes (i (length scores))
            (setf (aref cumuls (+ i 1))
                  (+ (aref cumuls i) (aref scores i))))
          #>cycle #>cumuls
          (dotimes (i len)
            (dotimes (stride len)
              (let ((incr (- (aref cumuls (+ i stride)) (aref cumuls i)))
                    (quot (floor (- k stride) len)))
                (dbg i stride incr quot)
                (unless (and (zerop stride) (zerop quot))
                  (maxf res (+ (* quot lap-sum) incr)))
                (unless (zerop stride)
                  (maxf res incr))))))))
    (sb-int:dovector (c cs)
      (maxf res c))
    (println res)))

#-swank (main)

;;;
;;; Test and benchmark
;;;

#+swank
(defun get-clipbrd ()
  (with-output-to-string (out)
    #+os-windows (run-program "powershell.exe" '("-Command" "Get-Clipboard") :output out :search t)
    #+os-unix (run-program "xsel" '("-b" "-o") :output out :search t)))

#+swank (defparameter *this-pathname* (uiop:current-lisp-file-pathname))
#+swank (defparameter *dat-pathname* (uiop:merge-pathnames* "test.dat" *this-pathname*))

#+swank
(defun run (&optional thing (out *standard-output*))
  "THING := null | string | symbol | pathname

null: run #'MAIN using the text on clipboard as input.
string: run #'MAIN using the string as input.
symbol: alias of FIVEAM:RUN!.
pathname: run #'MAIN using the text file as input."
  (let* ((*standard-output* (or out (make-string-output-stream)))
         (res (etypecase thing
                (null
                 (with-input-from-string (*standard-input* (delete #\Return (get-clipbrd)))
                   (main)))
                (string
                 (with-input-from-string (*standard-input* (delete #\Return thing))
                   (main)))
                (symbol (5am:run! thing))
                (pathname
                 (with-open-file (*standard-input* thing)
                   (main))))))
    (if out res (get-output-stream-string *standard-output*))))

#+swank
(defun gen-dat ()
  (uiop:with-output-file (out *dat-pathname* :if-exists :supersede)
    (format out "")))

#+swank
(defun bench (&optional (out (make-broadcast-stream)))
  (time (run *dat-pathname* out)))

;; To run: (5am:run! :sample)
#+swank
(it.bese.fiveam:test :sample
  (it.bese.fiveam:is
   (equal "8
"
          (run "5 2
2 4 5 1 3
3 4 -10 -8 8
" nil)))
  (it.bese.fiveam:is
   (equal "13
"
          (run "2 3
2 1
10 -7
" nil)))
  (it.bese.fiveam:is
   (equal "-1000
"
          (run "3 3
3 1 2
-1000 -2000 -3000
" nil)))
  (it.bese.fiveam:is
   (equal "29507023469
"
          (run "10 58
9 1 6 7 8 4 3 2 10 5
695279662 988782657 -119067776 382975538 -151885171 -177220596 -169777795 37619092 389386780 980092719
" nil))))