;; #!/usr/bin/env sbcl --script

(declaim (optimize (speed 3) (safety 0) (debug 0)))

(deftype uint8 () '(unsigned-byte 8))
(deftype int32 () '(signed-byte 32))

(declaim (type fixnum *ptr* *len*)
         (type (vector uint8 4096) *buf*))

(defvar *buf* (make-array 4096 :element-type 'uint8 :initial-element 0))
(defvar *ptr* (the fixnum 0))
(defvar *len* (the fixnum -1))

(defun refresh-buf ()
  (setf *len* (the fixnum (read-sequence *buf* *standard-input*)))
  (setf *ptr* (the fixnum 0)))

(declaim (ftype (function () uint8) my-read-char))
(defun my-read-char ()
  (when (>= *ptr* *len*) (refresh-buf))
  (if (>= *ptr* *len*)
      0
      (progn (incf *ptr*)
             (aref *buf* (1- *ptr*)))))

(declaim (ftype (function () int32) my-read-int))
(defun my-read-int ()
  (let ((is-negative nil)
        (result 0))
    (declare (type int32 result))
    (loop for cur-char = (my-read-char) then (my-read-char)
       while (and (/= cur-char (char-code #\-))
                  (/= 0)
                  (or (< cur-char 48)
                      (> cur-char 57)))
       finally (if (<= 48 cur-char 57)
                   (setf result (- cur-char 48))
                   (setf is-negative t)))
    (loop for cur-char = (my-read-char) then (my-read-char)
       while (<= 48 cur-char 57)
       do (setf result (+ (* result 10) (- cur-char 48))))
    (when is-negative (setf result (- result)))
    result))

(defun main ()
  (let* ((n (my-read-int))
         (k (my-read-int))
         (a (make-array n :element-type 'int32))
         (dp (make-array n :element-type 'int32 :initial-element (+ (expt 10 9) 100))))
    (dotimes (i n)
      (setf (aref a i) (my-read-int)))
    (setf (aref dp 0) 0)
    (loop for i of-type int32 from 0 below n do
      (loop with from-val of-type int32 = (aref dp i)
         for j of-type int32 from (1+ i) to (+ i k)
         while (< j n)
         for nval of-type int32 = (+ from-val (abs (- (aref a i) (aref a j))))
         if (< nval (aref dp j))
         do
           (setf (aref dp j) nval)))
    (format t "~a~%" (aref dp (- n 1)))))

(main)

;; (defun main2 ()
;;   (let* ((n (the int32 (read)))
;;          (k (the int32 (read)))
;;          (a (make-array n :element-type 'int32))
;;          (dp (make-array n :element-type 'int32 :initial-element (+ (expt 10 9) 100))))
;;     (let ((stream (make-string-input-stream (read-line))))
;;       (loop for i from 0
;;          for j = (read stream nil) until (null j)
;;          do (setf (aref a i) (the int32 j)))
;;     (setf (aref dp 0) 0)
;;     (loop for i of-type int32 from 0 below n do
;;       (loop with from-val of-type int32 = (aref dp i)
;;          for j of-type int32 from (1+ i) to (+ i k)
;;          while (< j n)
;;          do
;;            (let ((nval (the int32 (+ from-val (abs (- (aref a i) (aref a j)))))))
;;              (setf (aref dp j) (min (aref dp j) nval)))
;;     (format t "~a~%" (aref dp (- n 1)))))


;; #!/usr/bin/env sbcl --script

(declaim (optimize (speed 3) (safety 0) (debug 0)))

(deftype int32 () '(signed-byte 32))

(defun main ()
  (let* ((n (the int32 (read)))
         (k (the int32 (read)))
         (a (make-array n :element-type 'int32))
         (dp (make-array n :element-type 'int32 :initial-element (+ (expt 10 9) 100))))
    (dotimes (i n)
      (setf (aref a i) (the int32 (read))))
    (setf (aref dp 0) 0)
    (loop for i of-type int32 from 0 below n do
      (loop with from-val of-type int32 = (aref dp i)
         for j of-type int32 from (1+ i) to (+ i k)
         while (< j n)
         for nval of-type int32 = (+ from-val (abs (- (aref a i) (aref a j))))
         if (< nval (aref dp j))
         do
           (setf (aref dp j) nval)))
    (format t "~a~%" (aref dp (- n 1)))))

;; (defun main2 ()
;;   (let* ((n (the int32 (read)))
;;          (k (the int32 (read)))
;;          (a (make-array n :element-type 'int32))
;;          (dp (make-array n :element-type 'int32 :initial-element (+ (expt 10 9) 100))))
;;     (let ((stream (make-string-input-stream (read-line))))
;;       (loop for i from 0
;;          for j = (read stream nil) until (null j)
;;          do (setf (aref a i) (the int32 j)))
;;     (setf (aref dp 0) 0)
;;     (loop for i of-type int32 from 0 below n do
;;       (loop with from-val of-type int32 = (aref dp i)
;;          for j of-type int32 from (1+ i) to (+ i k)
;;          while (< j n)
;;          do
;;            (let ((nval (the int32 (+ from-val (abs (- (aref a i) (aref a j)))))))
;;              (setf (aref dp j) (min (aref dp j) nval)))
;;     (format t "~a~%" (aref dp (- n 1)))))

(main)

Global OOD problem IDs are disjoint from train, validation, and in-distribution test problem IDs.

Score : 100 points

Problem Statement

There are N stones, numbered 1, 2, \ldots, N.
For each i (1 \leq i \leq N), the height of Stone i is h_i.

There is a frog who is initially on Stone 1.
He will repeat the following action some number of times to reach Stone N:

If the frog is currently on Stone i, jump to one of the following: Stone i + 1, i + 2, \ldots, i + K. Here, a cost of |h_i - h_j| is incurred, where j is the stone to land on.

Find the minimum possible total cost incurred before the frog reaches Stone N.

Constraints

All values in input are integers.

2 \leq N \leq 10^5

1 \leq K \leq 100

1 \leq h_i \leq 10^4

Input

Input is given from Standard Input in the following format:

N K
h_1 h_2 \ldots h_N

Output

Print the minimum possible total cost incurred.

Sample Input 1

5 3
10 30 40 50 20

Sample Output 1

30

If we follow the path 1 → 2 → 5, the total cost incurred would be |10 - 30| + |30 - 20| = 30.

Sample Input 2

3 1
10 20 10

Sample Output 2

20

If we follow the path 1 → 2 → 3, the total cost incurred would be |10 - 20| + |20 - 10| = 20.

Sample Input 3

2 100
10 10

Sample Output 3

0

If we follow the path 1 → 2, the total cost incurred would be |10 - 10| = 0.

Sample Input 4

10 4
40 10 20 70 80 10 20 70 80 60

Sample Output 4

40

If we follow the path 1 → 4 → 8 → 10, the total cost incurred would be |40 - 70| + |70 - 70| + |70 - 60| = 40.

Submitted source-code file size, in bytes.

Execution CPU time reported by official Project CodeNet metadata, in milliseconds.

Peak memory usage reported by official Project CodeNet metadata, in kilobytes.


;; #!/usr/bin/env sbcl --script

(declaim (optimize (speed 3) (safety 0) (debug 0)))

(deftype int32 () '(signed-byte 32))

(defun main ()
  (let* ((n (read))
         (k (read))
         (a (make-array n :element-type 'int32))
         (dp (make-array n :element-type 'int32 :initial-element (+ (expt 10 9) 100))))
    (let ((stream (make-string-input-stream (read-line))))
      (loop for i from 0
         for j = (read stream nil) until (null j)
         do (setf (aref a i) (the int32 j))))
    (setf (aref dp 0) 0)
    (loop for i of-type int32 from 0 below n do
      (loop with from-val of-type int32 = (aref dp i)
         for j of-type int32 from (1+ i) to (+ i k)
         while (< j n)
         do
           (let ((nval (+ from-val (abs (- (aref a i) (aref a j))))))
             (setf (aref dp j) (min (aref dp j) nval)))))
    (format t "~a~%" (aref dp (- n 1)))))

(main)


;; #!/usr/bin/env sbcl --script

(declaim (optimize (speed 3) (safety 0) (debug 0)))

(deftype int32 () '(signed-byte 32))

(defun main ()
  (let* ((n (read))
         (k (read))
         (a (make-array n :element-type 'int32))
         (dp (make-array n :element-type 'int32 :initial-element (+ (expt 10 9) 100))))
    ;; (let ((stream (make-string-input-stream (read-line))))
    ;;   (loop for i from 0
    ;;      for j = (read stream nil) until (null j)
    ;;      do (setf (aref a i) j))
    (loop for i of-type int32 from 0 below n do (setf (aref a i) (read)))
    (setf (aref dp 0) 0)
    (loop for i of-type int32 from 0 below n do
      (loop with from-val of-type int32 = (aref dp i)
         for j of-type int32 from (1+ i) to (+ i k)
         while (< j n)
         do
           (let ((nval (+ from-val (abs (- (aref a i) (aref a j))))))
             (setf (aref dp j) (min (aref dp j) nval)))))
    (format t "~a~%" (aref dp (- n 1)))))

(main)


;; #!/usr/bin/env sbcl --script

;; (declaim (optimize (speed 3) (safety 0) (debug 0)))

(deftype int32 () '(signed-byte 32))

(defun main ()
  (let* ((n (read))
         (k (read))
         (a (make-array n :element-type 'int32))
         (dp (make-array n :element-type 'int32 :initial-element (+ (expt 10 9) 100))))
    ;; (let ((stream (make-string-input-stream (read-line))))
    ;;   (loop for i from 0
    ;;      for j = (read stream nil) until (null j)
    ;;      do (setf (aref a i) j))
    (loop for i of-type int32 from 0 below n do (setf (aref a i) (read)))
    (setf (aref dp 0) 0)
    (loop for i of-type int32 from 0 below n do
      (loop with from-val of-type int32 = (aref dp i)
         for j of-type int32 from (1+ i) to (+ i k)
         while (< j n)
         do
           (let ((nval (+ from-val (abs (- (aref a i) (aref a j))))))
             (setf (aref dp j) (min (aref dp j) nval)))))
    (format t "~a~%" (aref dp (- n 1)))))

(main)


;; #!/usr/bin/env sbcl --script

(declaim (optimize (speed 3) (safety 0) (debug 0)))

(defun main ()
  (let* ((n (read))
         (k (read))
         (a (make-array n :element-type 'fixnum))
         (dp (make-array n :element-type 'fixnum :initial-element (floor most-positive-fixnum 2))))
    (let ((stream (make-string-input-stream (read-line))))
      (loop for i from 0
         for j = (read stream nil) until (null j)
         do (setf (aref a i) j)))
    (setf (aref dp 0) 0)
    (dotimes (i n)
      (dotimes (j k)
        (when (>= (+ i j 1) n) (return))
        (let* ((jj (+ i j 1))
               (from-val (aref dp i))
               (to-val (aref dp jj))
               (nval (+ from-val (abs (- (aref a i) (aref a jj))))))
          (setf (aref dp jj) (min to-val nval)))))
    (format t "~a~%" (aref dp (- n 1)))))

(main)


;; #!/usr/bin/env sbcl --script

(declaim (optimize (speed 3) (safety 0) (debug 0)))

(defun main ()
  (let* ((n (read))
         (k (read))
         (a (make-array n :element-type 'fixnum))
         (dp (make-array n :element-type 'fixnum :initial-element (floor most-positive-fixnum 2))))
    (let ((stream (make-string-input-stream (read-line))))
      (loop for i from 0
         for j = (read stream nil) until (null j)
         do (setf (aref a i) j)))
    (flet ((relax (from to)
             (let* ((from-val (aref dp from))
                    (to-val (aref dp to))
                    (diff (abs (- (aref a to) (aref a from)))))
               (setf (aref dp to) (min to-val (+ from-val diff))))))
      (setf (aref dp 0) 0)
      (dotimes (i n)
        (dotimes (j k)
          (when (>= (+ i (1+ j)) n) (return))
          (when (< (+ i (1+ j)) n) (relax i (+ i (1+ j)))))))
    (format t "~a~%" (aref dp (- n 1)))))

(main)


;; #!/usr/bin/env sbcl --script

(declaim (optimize (speed 3) (safety 0) (debug 0)))

(defun main ()
  (let* ((n (read))
         (k (read))
         (a (make-array n :element-type 'fixnum))
         (dp (make-array n :element-type 'fixnum :initial-element (floor most-positive-fixnum 2))))
    (dotimes (i n)
      (setf (aref a i) (read)))
    (flet ((relax (from to)
             (declaim (inline relax))
             (let* ((from-val (aref dp from))
                    (to-val (aref dp to))
                    (diff (abs (- (aref a to) (aref a from)))))
               (setf (aref dp to) (min to-val (+ from-val diff))))))
      (setf (aref dp 0) 0)
      (dotimes (i n)
        (dotimes (j k)
          (when (< (+ i (1+ j)) n) (relax i (+ i (1+ j)))))))
    (format t "~a~%" (aref dp (- n 1)))))

(main)


;; #!/usr/bin/env sbcl --script

(defun main ()
  (let* ((n (read))
         (k (read))
         (a (make-array n :element-type 'fixnum))
         (dp (make-array n :element-type 'fixnum :initial-element (floor most-positive-fixnum 2))))
    (dotimes (i n)
      (setf (aref a i) (read)))
    ;; (flet ((relax (from to)
    ;;          (let* ((from-val (aref dp from))
    ;;                 (to-val (aref dp to))
    ;;                 (diff (abs (- (aref a to) (aref a from))))
    ;;            (setf (aref dp to) (min to-val (+ from-val diff))))
    ;;   (setf (aref dp 0) 0)
    ;;   (dotimes (i n)
    ;;     (dotimes (j k)
    ;;       (when (< (+ i (1+ j)) n) (relax i (+ i (1+ j))))))
    (format t "~a~%" (aref dp (- n 1)))))

(main)


;; #!/usr/bin/env sbcl --script

(defun main ()
  (let* ((n (read))
         (k (read))
         (a (make-array n :element-type 'fixnum))
         (dp (make-array n :element-type 'fixnum :initial-element (floor most-positive-fixnum 2))))
    (dotimes (i n)
      (setf (aref a i) (read)))
    (flet ((relax (from to)
             (let* ((from-val (aref dp from))
                    (to-val (aref dp to))
                    (diff (abs (- (aref a to) (aref a from)))))
               (setf (aref dp to) (min to-val (+ from-val diff))))))
      (setf (aref dp 0) 0)
      (dotimes (i n)
        (dotimes (j k)
          (when (< (+ i (1+ j)) n) (relax i (+ i (1+ j)))))))
    (format t "~a~%" (aref dp (- n 1)))))

(main)


#-(or child-sbcl swank)
(quit
 :unix-status
 (process-exit-code
  (run-program *runtime-pathname*
               '("--control-stack-size" "32MB"
                 "--noinform" "--disable-ldb" "--lose-on-corruption" "--end-runtime-options"
                 "--eval" "(push :child-sbcl *features*)"
                 "--script" #.(namestring *load-pathname*))
               :output t :error t :input t)))

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defparameter OPT
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0)))
  #+swank (progn (ql:quickload '(:cl-debug-print :fiveam))
                 (shadow :run)
                 (use-package :fiveam)))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)

;; BEGIN_INSERTED_CONTENTS

(declaim (inline split-ints-into-vector))
(defun split-ints-into-vector (str dest-arr &key (offset 0))
  (declare ((simple-array * (*)) dest-arr)
           ((integer 0 #.most-positive-fixnum) offset))
  (loop for idx from offset below (length dest-arr)
        for pos1 = 0 then (1+ pos2)
        for pos2 = (position #\space str :start pos1 :test #'char=)
        do (setf (aref dest-arr idx)
                 (parse-integer str :start pos1 :end pos2))
        finally (return dest-arr)))

(defmacro nlet (name args &body body)
  (labels ((ensure-list (x) (if (listp x) x (list x))))
    (let ((args (mapcar #'ensure-list args)))
      `(labels ((,name ,(mapcar #'car args) ,@body))
         (,name ,@(mapcar #'cadr args))))))

;; (with-memoizing (:hash-table :test #'equal :key #'cons)
;;   (defun ...))
;; (with-memoizing (:array (10 10 * 10) :initial-element -1 :element-type 'fixnum)
;;   (defun ...))
(defmacro with-memoizing (cache-attribs def-form)
  (let* ((cache-attribs (if (atom cache-attribs) (list cache-attribs) cache-attribs))
         (cache-type (first cache-attribs))
         (dimensions-with-* (when (eql cache-type :array) (second cache-attribs)))
         (dimensions (remove '* dimensions-with-*))
         (rank (length dimensions))
         (rest-attribs (ecase cache-type
                         (:hash-table (cdr cache-attribs))
                         (:array (cddr cache-attribs))))
         (key (prog1 (getf rest-attribs :key) (remf rest-attribs :key)))
         (cache-form (case cache-type
                       (:hash-table `(make-hash-table ,@rest-attribs))
                       (:array `(make-array ',dimensions ,@rest-attribs))))
         (initial-element (when (eql cache-type :array)
                            (assert (member :initial-element rest-attribs))
                            (getf rest-attribs :initial-element))))
    (let ((cache (gensym))
          (value (gensym))
	  (present-p (gensym))
          (name-alias (gensym))
	  (args-lst (gensym))
          (indices (loop repeat rank collect (gensym))))
      (labels ((make-cache-check-form (cache-type args)
                 (case cache-type
                   (:hash-table
                    `(let ((,args-lst (funcall ,(or key #'list) ,@args)))
                       (multiple-value-bind (,value ,present-p)
                           (gethash ,args-lst ,cache)
                         (if ,present-p
                             ,value
                             (setf (gethash ,args-lst ,cache)
                                   (,name-alias ,@args))))))
                   (:array
                    (let ((memoized-args (loop for dimension in dimensions-with-*
                                               for arg in args
                                               unless (eql dimension '*)
                                               collect arg)))
                      (if key
                          `(multiple-value-bind ,indices
                               (funcall ,key ,@memoized-args)
                             (let ((,value (aref ,cache ,@indices)))
                               (if (eql ,initial-element ,value)
                                   (setf (aref ,cache ,@indices)
                                         (,name-alias ,@args))
                                   ,value)))
                          `(let ((,value (aref ,cache ,@memoized-args)))
                             (if (eql ,initial-element ,value)
                                 (setf (aref ,cache ,@memoized-args)
                                       (,name-alias ,@args))
                                 ,value)))))))
               (make-reset-form (cache-type)
                 (case cache-type
                   (:hash-table `(setf ,cache (make-hash-table ,@rest-attribs)))
                   (:array `(prog1 nil
                              (fill (array-storage-vector ,cache) ,initial-element)))))
               (make-reset-name (name)
                 (intern (format nil "RESET-~A" (symbol-name name))))
               (extract-declarations (body)
                 (remove-if-not (lambda (form) (eql 'declare (car form))) body)))
        (ecase (car def-form)
          ((defun)
           (destructuring-bind (_ name args &body body) def-form
             (declare (ignore _))
             `(let ((,cache ,cache-form))
                (defun ,(make-reset-name name) () ,(make-reset-form cache-type))
                (defun ,name ,args
                  (labels ((,name-alias ,args ,@body))
                    (declare (inline ,name-alias))
                    ,@(extract-declarations body)
                    ,(make-cache-check-form cache-type args))))))
          ((nlet)
           (destructuring-bind (_ name bindings &body body) def-form
             (declare (ignore _))
             `(let ((,cache ,cache-form))
                (nlet ,name ,bindings
                      ,(let ((args (mapcar (lambda (x) (if (atom x) x (car x))) bindings)))
                         `(labels ((,name-alias ,args ,@body))
                            (declare (inline ,name-alias))
                            ,@(extract-declarations body)
                            ,(make-cache-check-form cache-type args)))))))
          ((labels flet)
           (destructuring-bind (_ definitions &body labels-body) def-form
             (declare (ignore _))
             (destructuring-bind (name args &body body) (car definitions)
               `(let ((,cache ,cache-form))
                  (,(car def-form)
                   ((,(make-reset-name name) () ,(make-reset-form cache-type))
                    (,name ,args
                           (labels ((,name-alias ,args ,@body))
                             (declare (inline ,name-alias))
                             ,@(extract-declarations body)
                             ,(make-cache-check-form cache-type args)))
                    ,@(cdr definitions))
                   (declare (ignorable #',(make-reset-name name)))
                   ,@labels-body))))))))))

;; (test with-memoizing
;;   (finishes (macroexpand `(with-memoizing (:hash-table :test #'equal)
;;                             (defun add (x y) (+ x y)))))
;;   (finishes (macroexpand `(with-memoizing (:array '(10 10)
;;                                            :element-type 'fixnum
;;                                            :initial-element -1)
;;                             (defun add (x y) (+ x y)))))
;;   (finishes (macroexpand `(with-memoizing (:array '(10 10)
;;                                            :element-type 'fixnum
;;                                            :initial-element -1)
;;                             (labels ((add (x y) (+ x y))
;; 		                     (my-print (x) (print x)))
;; 	                      (add 1 2))))))

(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 4 7 8 15 16 31 32 62 63 64)

(defmacro println (obj &optional (stream '*standard-output*))
  `(let ((*read-default-float-format* 'double-float))
     (prog1 (princ ,obj ,stream) (terpri ,stream))))

;; Hauptteil

(defun solve (hs k)
  (declare #.OPT
           ((simple-array uint32 (*)) hs)
           (uint32 k))
  (let ((dest (- (length hs) 1)))
    (with-memoizing (:array (100001) :element-type 'uint32
                     :initial-element #.(- (expt 2 32) 1))
      (nlet recurse ((i 0))
        (if (= i dest) 0
            (loop for delta from 1 to k
                  while (<= (+ i delta) dest)
                  minimize (+ (abs (- (aref hs i) (aref hs (+ i delta))))
                              (recurse (+ i delta)))))))))
(defun main ()
  (let* ((n (read))
         (k (read))
         (hs (make-array n :element-type 'uint32)))
    (split-ints-into-vector (read-line) hs)
    (println (solve hs k))))

#-swank(main)


#-(or child-sbcl swank)
(quit
 :unix-status
 (process-exit-code
  (run-program *runtime-pathname*
               '("--control-stack-size" "32MB"
                 "--noinform" "--disable-ldb" "--lose-on-corruption" "--end-runtime-options"
                 "--eval" "(push :child-sbcl *features*)"
                 "--script" #.(namestring *load-pathname*))
               :output t :error t :input t)))

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defparameter OPT
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0)))
  #+swank (progn (ql:quickload '(:cl-debug-print :fiveam))
                 (shadow :run)
                 (use-package :fiveam)))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)

;; BEGIN_INSERTED_CONTENTS

(declaim (inline split-ints-into-vector))
(defun split-ints-into-vector (str dest-arr &key (offset 0))
  (declare ((simple-array * (*)) dest-arr)
           ((integer 0 #.most-positive-fixnum) offset))
  (loop for idx from offset below (length dest-arr)
        for pos1 = 0 then (1+ pos2)
        for pos2 = (position #\space str :start pos1 :test #'char=)
        do (setf (aref dest-arr idx)
                 (parse-integer str :start pos1 :end pos2))
        finally (return dest-arr)))

(defmacro nlet (name args &body body)
  (labels ((ensure-list (x) (if (listp x) x (list x))))
    (let ((args (mapcar #'ensure-list args)))
      `(labels ((,name ,(mapcar #'car args) ,@body))
         (,name ,@(mapcar #'cadr args))))))

;; (with-memoizing (:hash-table :test #'equal :key #'cons)
;;   (defun ...))
;; (with-memoizing (:array (10 10 * 10) :initial-element -1 :element-type 'fixnum)
;;   (defun ...))
(defmacro with-memoizing (cache-attribs def-form)
  (let* ((cache-attribs (if (atom cache-attribs) (list cache-attribs) cache-attribs))
         (cache-type (first cache-attribs))
         (dimensions-with-* (when (eql cache-type :array) (second cache-attribs)))
         (dimensions (remove '* dimensions-with-*))
         (rank (length dimensions))
         (rest-attribs (ecase cache-type
                         (:hash-table (cdr cache-attribs))
                         (:array (cddr cache-attribs))))
         (key (prog1 (getf rest-attribs :key) (remf rest-attribs :key)))
         (cache-form (case cache-type
                       (:hash-table `(make-hash-table ,@rest-attribs))
                       (:array `(make-array ',dimensions ,@rest-attribs))))
         (initial-element (when (eql cache-type :array)
                            (assert (member :initial-element rest-attribs))
                            (getf rest-attribs :initial-element))))
    (let ((cache (gensym))
          (value (gensym))
	  (present-p (gensym))
          (name-alias (gensym))
	  (args-lst (gensym))
          (indices (loop repeat rank collect (gensym))))
      (labels ((make-cache-check-form (cache-type args)
                 (case cache-type
                   (:hash-table
                    `(let ((,args-lst (funcall ,(or key #'list) ,@args)))
                       (multiple-value-bind (,value ,present-p)
                           (gethash ,args-lst ,cache)
                         (if ,present-p
                             ,value
                             (setf (gethash ,args-lst ,cache)
                                   (,name-alias ,@args))))))
                   (:array
                    (let ((memoized-args (loop for dimension in dimensions-with-*
                                               for arg in args
                                               unless (eql dimension '*)
                                               collect arg)))
                      (if key
                          `(multiple-value-bind ,indices
                               (funcall ,key ,@memoized-args)
                             (let ((,value (aref ,cache ,@indices)))
                               (if (eql ,initial-element ,value)
                                   (setf (aref ,cache ,@indices)
                                         (,name-alias ,@args))
                                   ,value)))
                          `(let ((,value (aref ,cache ,@memoized-args)))
                             (if (eql ,initial-element ,value)
                                 (setf (aref ,cache ,@memoized-args)
                                       (,name-alias ,@args))
                                 ,value)))))))
               (make-reset-form (cache-type)
                 (case cache-type
                   (:hash-table `(setf ,cache (make-hash-table ,@rest-attribs)))
                   (:array `(prog1 nil
                              (fill (array-storage-vector ,cache) ,initial-element)))))
               (make-reset-name (name)
                 (intern (format nil "RESET-~A" (symbol-name name))))
               (extract-declarations (body)
                 (remove-if-not (lambda (form) (eql 'declare (car form))) body)))
        (ecase (car def-form)
          ((defun)
           (destructuring-bind (_ name args &body body) def-form
             (declare (ignore _))
             `(let ((,cache ,cache-form))
                (defun ,(make-reset-name name) () ,(make-reset-form cache-type))
                (defun ,name ,args
                  (labels ((,name-alias ,args ,@body))
                    (declare (inline ,name-alias))
                    ,@(extract-declarations body)
                    ,(make-cache-check-form cache-type args))))))
          ((nlet)
           (destructuring-bind (_ name bindings &body body) def-form
             (declare (ignore _))
             `(let ((,cache ,cache-form))
                (nlet ,name ,bindings
                      ,(let ((args (mapcar (lambda (x) (if (atom x) x (car x))) bindings)))
                         `(labels ((,name-alias ,args ,@body))
                            (declare (inline ,name-alias))
                            ,@(extract-declarations body)
                            ,(make-cache-check-form cache-type args)))))))
          ((labels flet)
           (destructuring-bind (_ definitions &body labels-body) def-form
             (declare (ignore _))
             (destructuring-bind (name args &body body) (car definitions)
               `(let ((,cache ,cache-form))
                  (,(car def-form)
                   ((,(make-reset-name name) () ,(make-reset-form cache-type))
                    (,name ,args
                           (labels ((,name-alias ,args ,@body))
                             (declare (inline ,name-alias))
                             ,@(extract-declarations body)
                             ,(make-cache-check-form cache-type args)))
                    ,@(cdr definitions))
                   (declare (ignorable #',(make-reset-name name)))
                   ,@labels-body))))))))))

;; (test with-memoizing
;;   (finishes (macroexpand `(with-memoizing (:hash-table :test #'equal)
;;                             (defun add (x y) (+ x y)))))
;;   (finishes (macroexpand `(with-memoizing (:array '(10 10)
;;                                            :element-type 'fixnum
;;                                            :initial-element -1)
;;                             (defun add (x y) (+ x y)))))
;;   (finishes (macroexpand `(with-memoizing (:array '(10 10)
;;                                            :element-type 'fixnum
;;                                            :initial-element -1)
;;                             (labels ((add (x y) (+ x y))
;; 		                     (my-print (x) (print x)))
;; 	                      (add 1 2))))))

(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 4 7 8 15 16 31 32 62 63 64)

(defmacro println (obj &optional (stream '*standard-output*))
  `(let ((*read-default-float-format* 'double-float))
     (prog1 (princ ,obj ,stream) (terpri ,stream))))

;; Hauptteil

(defun solve (hs k)
  (let ((dest (- (length hs) 1)))
    (with-memoizing (:array (100001) :element-type 'uint32
                     :initial-element #.(- (expt 2 32) 1))
      (nlet recurse ((i 0))
        (if (= i dest) 0
            (loop for delta from 1 to k
                  while (<= (+ i delta) dest)
                  minimize (+ (abs (- (aref hs i) (aref hs (+ i delta))))
                              (recurse (+ i delta)))))))))
(defun main ()
  (let* ((n (read))
         (k (read))
         (hs (make-array n :element-type 'uint32)))
    (split-ints-into-vector (read-line) hs)
    (println (solve hs k))))

#-swank(main)


;; Utils

;; Read fixnum

(declaim (ftype (function * (values fixnum &optional)) read-fixnum))
(defun read-fixnum (&optional (in *standard-input*))
  (declare (inline read-byte)
           #-swank (sb-kernel:ansi-stream in))
  (macrolet ((%read-byte ()
               `(the (unsigned-byte 8)
                     #+swank (char-code (read-char in nil #\Nul))
                     #-swank (read-byte in nil 0))))
    (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) (the (integer 0 #.(floor most-positive-fixnum 10)) (* result 10))))
              (return (if minus (- result) result))))))))

;; fast read-line

(defmacro buffered-read-line (&optional (buffer-size 30) (in '*standard-input*) (term-char #\Space))
  (let ((buffer (gensym))
        (character (gensym))
        (idx (gensym)))
    `(let* ((,buffer (load-time-value (make-string ,buffer-size :element-type 'base-char))))
       (declare (simple-base-string ,buffer)
                (inline read-byte))
       (loop for ,character of-type base-char =
             ,(if (member :swank *features*)
                  `(read-char ,in nil #\Newline) ; on SLIME
                `(code-char (read-byte ,in nil #.(char-code #\Newline))))
             for ,idx from 0
             until (char= ,character #\Newline)
             do (setf (schar ,buffer ,idx) ,character)
             finally (when (< ,idx ,buffer-size)
                       (setf (schar ,buffer ,idx) ,term-char))
             (return (values ,buffer ,idx))))))

;;; invoke child process

#-swank
(unless (member :child-sbcl *features*)
  (quit
    :unix-status
    (process-exit-code
      (run-program *runtime-pathname*
                   `("--control-stack-size" "128MB"
                     "--noinform" "--disable-ldb" "--lose-on-corruption" "--end-runtime-options"
                     "--eval" "(push :child-sbcl *features*)"
                     "--script" ,(namestring *load-pathname*))
                                                                 :output t :error t :input t))))

;-------------------
; Write code here
;-------------------

(defparameter *inf* (expt 10 10))

(defun solve (n weight-limit l)
  (let ((memo (make-array (list (1+ n) (1+ weight-limit)) :initial-element -1)))
    (labels ((dp (i w)
               ; 1 ~ iまでの品物での価値の最大化
               (cond
                 ((< w 0) (- *inf*))
                 ((zerop i) 0)
                 ((/= (aref memo i w) -1) (aref memo i w))
                 (t
                  (let ((weight (aref l (1- i) 0))
                        (value  (aref l (1- i) 1)))
                    (let ((res (max (dp (1- i) w)
                                    (+ (dp (1- i) (- w weight))
                                       value))))
                      (setf (aref memo i w) res)
                      res))))))
      (dp n weight-limit))))

(defun main ()
  (let* ((n (read))
         (weight-limit (read))
         (l (make-array (list n 2))))
    (dotimes (i n)
      (setf (aref l i 0) (read))
      (setf (aref l i 1) (read)))
    (princ (solve n weight-limit l))
    (fresh-line)))

(main)

Score : 100 points

Problem Statement

There are N items, numbered 1, 2, \ldots, N.
For each i (1 \leq i \leq N), Item i has a weight of w_i and a value of v_i.

Taro has decided to choose some of the N items and carry them home in a knapsack.
The capacity of the knapsack is W, which means that the sum of the weights of items taken must be at most W.

Find the maximum possible sum of the values of items that Taro takes home.

Constraints

All values in input are integers.

1 \leq N \leq 100

1 \leq W \leq 10^5

1 \leq w_i \leq W

1 \leq v_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N W
w_1 v_1
w_2 v_2
:
w_N v_N

Output

Print the maximum possible sum of the values of items that Taro takes home.

Sample Input 1

3 8
3 30
4 50
5 60

Sample Output 1

90

Items 1 and 3 should be taken.
Then, the sum of the weights is 3 + 5 = 8, and the sum of the values is 30 + 60 = 90.

Sample Input 2

5 5
1 1000000000
1 1000000000
1 1000000000
1 1000000000
1 1000000000

Sample Output 2

5000000000

The answer may not fit into a 32-bit integer type.

Sample Input 3

6 15
6 5
5 6
6 4
6 6
3 5
7 2

Sample Output 3

17

Items 2, 4 and 5 should be taken.
Then, the sum of the weights is 5 + 6 + 3 = 14, and the sum of the values is 6 + 6 + 5 = 17.


(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)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
(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))

(declaim (ftype (function * (values fixnum &optional)) read-fixnum))
(defun read-fixnum (&optional (in *standard-input*))
  "NOTE: cannot read -2^62"
  (declare #.OPT)
  (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))))))))

(in-package :cl-user)

(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)))

(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)

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

(defconstant +mod+ 1000000007)

;;;
;;; Body
;;;

(defun main ()
  (declare #.OPT)
  (let* ((n (read-fixnum))
         (limit (read-fixnum))
         (dp (make-array (+ limit 1) :element-type 'fixnum :initial-element 0)))
    (dotimes (x n)
      (let ((w (read-fixnum))
            (v (read-fixnum)))
        (loop for y from limit downto 0
              do (setf (aref dp y)
                       (if (>= y w)
                           (max (+ v (aref dp (- y w))) (aref dp y))
                           (aref dp y))))))
    (println (aref dp limit))))

#-swank (main)

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

#+swank
(defun io-equal (in-string out-string &key (function #'main) (test #'equal))
  "Passes IN-STRING to *STANDARD-INPUT*, executes FUNCTION, and returns true if
the string output to *STANDARD-OUTPUT* is equal to OUT-STRING."
  (labels ((ensure-last-lf (s)
             (if (eql (uiop:last-char s) #\Linefeed)
                 s
                 (uiop:strcat s uiop:+lf+))))
    (funcall test
             (ensure-last-lf out-string)
             (with-output-to-string (out)
               (let ((*standard-output* out))
                 (with-input-from-string (*standard-input* (ensure-last-lf in-string))
                   (funcall function)))))))

#+swank
(defun get-clipbrd ()
  (with-output-to-string (out)
    (run-program "powershell.exe" '("-Command" "Get-Clipboard") :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* out))
    (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))))))

#+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
   (common-lisp-user::io-equal "3 8
3 30
4 50
5 60
"
    "90
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "5 5
1 1000000000
1 1000000000
1 1000000000
1 1000000000
1 1000000000
"
    "5000000000
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "6 15
6 5
5 6
6 4
6 6
3 5
7 2
"
    "17
")))


(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)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
(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))

(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))))))))

(in-package :cl-user)

(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)))

(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)

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

(defconstant +mod+ 1000000007)

;;;
;;; Body
;;;

(defun main ()
  (let* ((n (read-fixnum))
         (limit (read-fixnum))
         (dp (make-array (list (+ n 1) (+ limit 1))
                         :element-type 'fixnum
                         :initial-element 0))
         (ws (make-array n :element-type 'uint32 :initial-element 0))
         (vs (make-array n :element-type 'uint32 :initial-element 0)))
    (dotimes (i n)
      (setf (aref ws i) (read-fixnum)
            (aref vs i) (read-fixnum)))
    (loop for x from 1 to n
          for w = (aref ws (- x 1))
          for v = (aref vs (- x 1))
          do (dotimes (y (+ limit 1))
               (setf (aref dp x y)
                     (if (>= y w)
                         (max (+ v (aref dp (- x 1) (- y w)))
                              (aref dp (- x 1) y))
                         (aref dp (- x 1) y)))))
    (println (aref dp n limit))))

#-swank (main)

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

#+swank
(defun io-equal (in-string out-string &key (function #'main) (test #'equal))
  "Passes IN-STRING to *STANDARD-INPUT*, executes FUNCTION, and returns true if
the string output to *STANDARD-OUTPUT* is equal to OUT-STRING."
  (labels ((ensure-last-lf (s)
             (if (eql (uiop:last-char s) #\Linefeed)
                 s
                 (uiop:strcat s uiop:+lf+))))
    (funcall test
             (ensure-last-lf out-string)
             (with-output-to-string (out)
               (let ((*standard-output* out))
                 (with-input-from-string (*standard-input* (ensure-last-lf in-string))
                   (funcall function)))))))

#+swank
(defun get-clipbrd ()
  (with-output-to-string (out)
    (run-program "powershell.exe" '("-Command" "Get-Clipboard") :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* out))
    (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))))))

#+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
   (common-lisp-user::io-equal "3 8
3 30
4 50
5 60
"
    "90
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "5 5
1 1000000000
1 1000000000
1 1000000000
1 1000000000
1 1000000000
"
    "5000000000
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "6 15
6 5
5 6
6 4
6 6
3 5
7 2
"
    "17
")))


(unless (member :child-sbcl *features*)
  #-swank (quit
            :unix-status
            (process-exit-code
              (run-program *runtime-pathname*
                           `("--control-stack-size" "128MB"
                             "--noinform"
                             "--disable-ldb"
                             "--lose-on-corruption"
                             "--end-runtime-options"
                             "--eval" "(push :child-sbcl *features*)"
                             "--script" ,(namestring *load-pathname*))
                           :output t :error t :input t))))

(eval-when (:compile-toplevel)
  #-swank (proclaim '(optimize (speed 3) (debug 0) (safety 0))))

(eval-when (:compile-toplevel :load-toplevel :execute)
  (labels ((array-reference-reader (stream c n)
             "Reader macro #&(array index) => (aref array index)"
             (declare (ignore c n))
             (let ((list (read stream)))
               `(aref ,(car list) ,@(cdr list)))))
    (setf *readtable* (copy-readtable))
    (set-dispatch-macro-character #\# #\& #'array-reference-reader)))

(defconstant mod-number 1000000007)
(defconstant inf 2000000000)

(defmacro let-if (var cond tbody &optional fbody)
  `(let ((,var ,cond))
     (if ,var
         ,tbody
         ,fbody)))

(defun unfold (p f g seed &optional (tail-gen (lambda () '())))
  (if (p seed)
      (tail-gen seed)
      (cons (f seed)
            (unfold p f g (g seed) tail-gen))))

(defun iota (c &optional (s 0) (step 1) (acc nil))
  (if (zerop c)
      (nreverse acc)
      (iota (1- c) (+ s step) step (cons s acc))))

(defun sum (list &optional (init 0))
  (reduce #'+ list :initial-value init))

(defun chomp (str)
  (string-right-trim '(#\Return #\Linefeed) str))

(defun read-integer (&optional (in *standard-input*))
  (declare (inline read-byte))
  (labels ((number-char-p (b)
             (<= #.(char-code #\0) b #.(char-code #\9)))
           (minus-char-p (b)
             (= b #.(char-code #\-)))
           (to-number (b)
             (- b #.(char-code #\0))))
    (declare (inline number-char-p minus-char-p to-number))
    (macrolet ((%read-byte ()
                 '(the (unsigned-byte 8)
                       #+swank (char-code (read-char in nil #\Nul))
                       #-swank (read-byte in nil 0))))
      (let* ((minus-p nil)
             (x (loop for b = (%read-byte)
                      if (number-char-p b)
                        return (to-number b)
                        end
                      if (minus-char-p b)
                        do (setf minus-p t))))
        (declare (boolean minus-p) (fixnum x))
        (the fixnum (loop for b = (%read-byte)
                          and y = x then (+ (* y 10) (to-number b))
                          unless (number-char-p b)
                            return (funcall (if minus-p #'- #'+) y)))))))

(defun split (x str &optional (acc nil))
  (let ((pos (search x str))
        (size (length x)))
    (if pos
        (split x (subseq str (+ pos size)) (cons (subseq str 0 pos) acc))
        (nreverse (cons str acc)))))

(defmacro minf (field &rest x)
  `(setf ,field (min ,field ,@x)))

(defmacro maxf (field &rest x)
  `(setf ,field (max ,field ,@x)))

(defmacro debug-print (x)
  `(let ((y ,x))
    (format t "~A: ~A~%" ',x y)
    y))

(defmacro defdp (name args &body body)
  (let ((argc (length args))
        (key (gensym)))
    `(let ((dp (make-hash-table :test #'equal)))
       (defun ,name ,args
         (let ((,key ,@(if (= argc 1) args `((list ,@args)))))
           (let-if memo (gethash ,key dp)
                   memo
                   (setf (gethash ,key dp)
                         (progn ,@body))))))))

(defparameter n (read))
(defparameter w-max (read))
(defparameter w (make-array n))
(defparameter v (make-array n))
(dotimes (i n)
  (setf #&(w i) (read))
  (setf #&(v i) (read)))

(defdp solve (index weight)
  (cond ((< weight 0) (- inf))
        ((< index 0) 0)
        (t (max (+ (solve (1- index) (- weight #&(w index)))
                   #&(v index))
                (solve (1- index) weight)))))

;; (format t "~A~%" (solve (1- n) w-max))


(unless (member :child-sbcl *features*)
  #-swank (quit
            :unix-status
            (process-exit-code
              (run-program *runtime-pathname*
                           `("--control-stack-size" "128MB"
                             "--noinform"
                             "--disable-ldb"
                             "--lose-on-corruption"
                             "--end-runtime-options"
                             "--eval" "(push :child-sbcl *features*)"
                             "--script" ,(namestring *load-pathname*))
                           :output t :error t :input t))))

(eval-when (:compile-toplevel)
  #-swank (proclaim '(optimize (speed 3) (debug 0) (safety 0))))

(eval-when (:compile-toplevel :load-toplevel :execute)
  (labels ((array-reference-reader (stream c n)
             "Reader macro #&(array index) => (aref array index)"
             (declare (ignore c n))
             (let ((list (read stream)))
               `(aref ,(car list) ,@(cdr list)))))
    (setf *readtable* (copy-readtable))
    (set-dispatch-macro-character #\# #\& #'array-reference-reader)))

(defconstant mod-number 1000000007)
(defconstant inf 2000000000)

(defmacro let-if (var cond tbody &optional fbody)
  `(let ((,var ,cond))
     (if ,var
         ,tbody
         ,fbody)))

(defun unfold (p f g seed &optional (tail-gen (lambda () '())))
  (if (p seed)
      (tail-gen seed)
      (cons (f seed)
            (unfold p f g (g seed) tail-gen))))

(defun iota (c &optional (s 0) (step 1) (acc nil))
  (if (zerop c)
      (nreverse acc)
      (iota (1- c) (+ s step) step (cons s acc))))

(defun sum (list &optional (init 0))
  (reduce #'+ list :initial-value init))

(defun chomp (str)
  (string-right-trim '(#\Return #\Linefeed) str))

(defun read-integer (&optional (in *standard-input*))
  (declare (inline read-byte))
  (labels ((number-char-p (b)
             (<= #.(char-code #\0) b #.(char-code #\9)))
           (minus-char-p (b)
             (= b #.(char-code #\-)))
           (to-number (b)
             (- b #.(char-code #\0))))
    (declare (inline number-char-p minus-char-p to-number))
    (macrolet ((%read-byte ()
                 '(the (unsigned-byte 8)
                       #+swank (char-code (read-char in nil #\Nul))
                       #-swank (read-byte in nil 0))))
      (let* ((minus-p nil)
             (x (loop for b = (%read-byte)
                      if (number-char-p b)
                        return (to-number b)
                        end
                      if (minus-char-p b)
                        do (setf minus-p t))))
        (declare (boolean minus-p) (fixnum x))
        (the fixnum (loop for b = (%read-byte)
                          and y = x then (+ (* y 10) (to-number b))
                          unless (number-char-p b)
                            return (funcall (if minus-p #'- #'+) y)))))))

(defun split (x str &optional (acc nil))
  (let ((pos (search x str))
        (size (length x)))
    (if pos
        (split x (subseq str (+ pos size)) (cons (subseq str 0 pos) acc))
        (nreverse (cons str acc)))))

(defmacro minf (field &rest x)
  `(setf ,field (min ,field ,@x)))

(defmacro maxf (field &rest x)
  `(setf ,field (max ,field ,@x)))

(defmacro debug-print (x)
  `(let ((y ,x))
    (format t "~A: ~A~%" ',x y)
    y))

(defmacro defdp (name args &body body)
  (let ((argc (length args))
        (key (gensym)))
    `(let ((dp (make-hash-table :test #'equal)))
       (defun ,name ,args
         (let ((,key ,@(if (= argc 1) args `((list ,@args)))))
           (let-if memo (gethash ,key dp)
                   memo
                   (setf (gethash ,key dp)
                         (progn ,@body))))))))

(defparameter n (read-integer))
(defparameter w-max (read-integer))
(defparameter w (make-array n :element-type 'fixnum))
(defparameter v (make-array n :element-type 'fixnum))
(dotimes (i n)
  (setf #&(w i) (read-integer))
  (setf #&(v i) (read-integer)))

(defdp solve (index weight)
  (the fixnum
       (cond ((< weight 0) (- (the fixnum inf)))
             ((< index 0) 0)
             (t (max (+ (the fixnum (solve (1- index) (- weight #&(w index))))
                        (the fixnum #&(v index)))
                     (the fixnum (solve (1- index) weight)))))))

(format t "~A~%" (the fixnum (solve (1- n) w-max)))


(unless (member :child-sbcl *features*)
  #-swank (quit
            :unix-status
            (process-exit-code
              (run-program *runtime-pathname*
                           `("--control-stack-size" "128MB"
                             "--noinform"
                             "--disable-ldb"
                             "--lose-on-corruption"
                             "--end-runtime-options"
                             "--eval" "(push :child-sbcl *features*)"
                             "--script" ,(namestring *load-pathname*))
                           :output t :error t :input t))))

(eval-when (:compile-toplevel)
  #-swank (proclaim '(optimize (speed 3) (debug 0) (safety 0))))

(eval-when (:compile-toplevel :load-toplevel :execute)
  (labels ((array-reference-reader (stream c n)
             "Reader macro #&(array index) => (aref array index)"
             (declare (ignore c n))
             (let ((list (read stream)))
               `(aref ,(car list) ,@(cdr list)))))
    (setf *readtable* (copy-readtable))
    (set-dispatch-macro-character #\# #\& #'array-reference-reader)))

(defconstant mod-number 1000000007)
(defconstant inf 2000000000)

(defmacro let-if (var cond tbody &optional fbody)
  `(let ((,var ,cond))
     (if ,var
         ,tbody
         ,fbody)))

(defun unfold (p f g seed &optional (tail-gen (lambda () '())))
  (if (p seed)
      (tail-gen seed)
      (cons (f seed)
            (unfold p f g (g seed) tail-gen))))

(defun iota (c &optional (s 0) (step 1) (acc nil))
  (if (zerop c)
      (nreverse acc)
      (iota (1- c) (+ s step) step (cons s acc))))

(defun sum (list &optional (init 0))
  (reduce #'+ list :initial-value init))

(defun chomp (str)
  (string-right-trim '(#\Return #\Linefeed) str))

(defun read-integer (&optional (in *standard-input*))
  (declare (inline read-byte))
  (labels ((number-char-p (b)
             (<= #.(char-code #\0) b #.(char-code #\9)))
           (minus-char-p (b)
             (= b #.(char-code #\-)))
           (to-number (b)
             (- b #.(char-code #\0))))
    (declare (inline number-char-p minus-char-p to-number))
    (macrolet ((%read-byte ()
                 '(the (unsigned-byte 8)
                       #+swank (char-code (read-char in nil #\Nul))
                       #-swank (read-byte in nil 0))))
      (let* ((minus-p nil)
             (x (loop for b = (%read-byte)
                      if (number-char-p b)
                        return (to-number b)
                        end
                      if (minus-char-p b)
                        do (setf minus-p t))))
        (declare (boolean minus-p) (fixnum x))
        (the fixnum (loop for b = (%read-byte)
                          and y = x then (+ (* y 10) (to-number b))
                          unless (number-char-p b)
                            return (funcall (if minus-p #'- #'+) y)))))))

(defun split (x str &optional (acc nil))
  (let ((pos (search x str))
        (size (length x)))
    (if pos
        (split x (subseq str (+ pos size)) (cons (subseq str 0 pos) acc))
        (nreverse (cons str acc)))))

(defmacro minf (field &rest x)
  `(setf ,field (min ,field ,@x)))

(defmacro maxf (field &rest x)
  `(setf ,field (max ,field ,@x)))

(defmacro debug-print (x)
  `(let ((y ,x))
    (format t "~A: ~A~%" ',x y)
    y))

(defmacro defdp (name args &body body)
  (let ((argc (length args))
        (key (gensym)))
    `(let ((dp (make-hash-table :test #'equal)))
       (defun ,name ,args
         (let ((,key ,@(if (= argc 1) args `((list ,@args)))))
           (let-if memo (gethash ,key dp)
                   memo
                   (setf (gethash ,key dp)
                         (progn ,@body))))))))

(defparameter n (read-integer))
(defparameter w-max (read-integer))
(defparameter w (make-array n))
(defparameter v (make-array n))
(dotimes (i n)
  (setf #&(w i) (read-integer))
  (setf #&(v i) (read-integer)))

(defdp solve (index weight)
  (cond ((< weight 0) (- inf))
        ((< index 0) 0)
        (t (max (+ (solve (1- index) (- weight #&(w index)))
                   #&(v index))
                (solve (1- index) weight)))))

;; (format t "~A~%" (solve (1- n) w-max))


(unless (member :child-sbcl *features*)
  #-swank (quit
            :unix-status
            (process-exit-code
              (run-program *runtime-pathname*
                           `("--control-stack-size" "128MB"
                             "--noinform"
                             "--disable-ldb"
                             "--lose-on-corruption"
                             "--end-runtime-options"
                             "--eval" "(push :child-sbcl *features*)"
                             "--script" ,(namestring *load-pathname*))
                           :output t :error t :input t))))

(eval-when (:compile-toplevel)
  #-swank (proclaim '(optimize (speed 3) (debug 0) (safety 0))))

(eval-when (:compile-toplevel :load-toplevel :execute)
  (labels ((array-reference-reader (stream c n)
             "Reader macro #&(array index) => (aref array index)"
             (declare (ignore c n))
             (let ((list (read stream)))
               `(aref ,(car list) ,@(cdr list)))))
    (setf *readtable* (copy-readtable))
    (set-dispatch-macro-character #\# #\& #'array-reference-reader)))

(defconstant mod-number 1000000007)
(defconstant inf 2000000000)

(defmacro let-if (var cond tbody &optional fbody)
  `(let ((,var ,cond))
     (if ,var
         ,tbody
         ,fbody)))

(defun unfold (p f g seed &optional (tail-gen (lambda () '())))
  (if (p seed)
      (tail-gen seed)
      (cons (f seed)
            (unfold p f g (g seed) tail-gen))))

(defun iota (c &optional (s 0) (step 1) (acc nil))
  (if (zerop c)
      (nreverse acc)
      (iota (1- c) (+ s step) step (cons s acc))))

(defun sum (list &optional (init 0))
  (reduce #'+ list :initial-value init))

(defun chomp (str)
  (string-right-trim '(#\Return #\Linefeed) str))

(defun read-integer (&optional (in *standard-input*))
  (declare (inline read-byte))
  (labels ((number-char-p (b)
             (<= #.(char-code #\0) b #.(char-code #\9)))
           (minus-char-p (b)
             (= b #.(char-code #\-)))
           (to-number (b)
             (- b #.(char-code #\0))))
    (declare (inline number-char-p minus-char-p to-number))
    (macrolet ((%read-byte ()
                 '(the (unsigned-byte 8)
                       #+swank (char-code (read-char in nil #\Nul))
                       #-swank (read-byte in nil 0))))
      (let* ((minus-p nil)
             (x (loop for b = (%read-byte)
                      if (number-char-p b)
                        return (to-number b)
                        end
                      if (minus-char-p b)
                        do (setf minus-p t))))
        (declare (boolean minus-p) (fixnum x))
        (the fixnum (loop for b = (%read-byte)
                          and y = x then (+ (* y 10) (to-number b))
                          unless (number-char-p b)
                            return (funcall (if minus-p #'- #'+) y)))))))

(defun split (x str &optional (acc nil))
  (let ((pos (search x str))
        (size (length x)))
    (if pos
        (split x (subseq str (+ pos size)) (cons (subseq str 0 pos) acc))
        (nreverse (cons str acc)))))

(defmacro minf (field &rest x)
  `(setf ,field (min ,field ,@x)))

(defmacro maxf (field &rest x)
  `(setf ,field (max ,field ,@x)))

(defmacro debug-print (x)
  `(let ((y ,x))
    (format t "~A: ~A~%" ',x y)
    y))

(defmacro defdp (name args &body body)
  (let ((argc (length args))
        (key (gensym)))
    `(let ((dp (make-hash-table :test #'equal)))
       (defun ,name ,args
         (let ((,key ,@(if (= argc 1) args `((list ,@args)))))
           (let-if memo (gethash ,key dp)
                   memo
                   (setf (gethash ,key dp)
                         (progn ,@body))))))))

(defparameter n (read-integer))
(defparameter w-max (read-integer))
(defparameter w (make-array n))
(defparameter v (make-array n))
(dotimes (i n)
  (setf #&(w i) (read-integer))
  (setf #&(v i) (read-integer)))

(defdp solve (index weight)
  (cond ((< weight 0) (- inf))
        ((< index 0) 0)
        (t (max (+ (solve (1- index) (- weight #&(w index)))
                   #&(v index))
                (solve (1- index) weight)))))

(format t "~A~%" (solve (1- n) w-max))


(unless (member :child-sbcl *features*)
  #-swank (quit
            :unix-status
            (process-exit-code
              (run-program *runtime-pathname*
                           `("--control-stack-size" "128MB"
                             "--noinform"
                             "--disable-ldb"
                             "--lose-on-corruption"
                             "--end-runtime-options"
                             "--eval" "(push :child-sbcl *features*)"
                             "--script" ,(namestring *load-pathname*))
                           :output t :error t :input t))))

(eval-when (:compile-toplevel)
  #-swank (proclaim '(optimize (speed 3) (debug 0) (safety 0))))

(eval-when (:compile-toplevel :load-toplevel :execute)
  (labels ((array-reference-reader (stream c n)
             "Reader macro #&(array index) => (aref array index)"
             (declare (ignore c n))
             (let ((list (read stream)))
               `(aref ,(car list) ,@(cdr list)))))
    (setf *readtable* (copy-readtable))
    (set-dispatch-macro-character #\# #\& #'array-reference-reader)))

(defconstant mod-number 1000000007)
(defconstant inf 1000000000000000)

(defmacro let-if (var cond tbody &optional fbody)
  `(let ((,var ,cond))
     (if ,var
         ,tbody
         ,fbody)))

(defun unfold (p f g seed &optional (tail-gen (lambda () '())))
  (if (p seed)
      (tail-gen seed)
      (cons (f seed)
            (unfold p f g (g seed) tail-gen))))

(defun iota (c &optional (s 0) (step 1) (acc nil))
  (if (zerop c)
      (nreverse acc)
      (iota (1- c) (+ s step) step (cons s acc))))

(defun sum (list &optional (init 0))
  (reduce #'+ list :initial-value init))

(defun chomp (str)
  (string-right-trim '(#\Return #\Linefeed) str))

(defun read-integer (&optional (in *standard-input*))
  (declare (inline read-byte))
  (labels ((number-char-p (b)
             (<= #.(char-code #\0) b #.(char-code #\9)))
           (minus-char-p (b)
             (= b #.(char-code #\-)))
           (to-number (b)
             (- b #.(char-code #\0))))
    (declare (inline number-char-p minus-char-p to-number))
    (macrolet ((%read-byte ()
                 '(the (unsigned-byte 8)
                       #+swank (char-code (read-char in nil #\Nul))
                       #-swank (read-byte in nil 0))))
      (let* ((minus-p nil)
             (x (loop for b = (%read-byte)
                      if (number-char-p b)
                        return (to-number b)
                        end
                      if (minus-char-p b)
                        do (setf minus-p t))))
        (declare (boolean minus-p) (fixnum x))
        (the fixnum (loop for b = (%read-byte)
                          and y = x then (+ (* y 10) (to-number b))
                          unless (number-char-p b)
                            return (funcall (if minus-p #'- #'+) y)))))))

(defun split (x str &optional (acc nil))
  (let ((pos (search x str))
        (size (length x)))
    (if pos
        (split x (subseq str (+ pos size)) (cons (subseq str 0 pos) acc))
        (nreverse (cons str acc)))))

(defmacro minf (field &rest x)
  `(setf ,field (min ,field ,@x)))

(defmacro maxf (field &rest x)
  `(setf ,field (max ,field ,@x)))

(defmacro debug-print (x)
  `(let ((y ,x))
    (format t "~A: ~A~%" ',x y)
    y))

(defmacro defdp (name args &body body)
  (let ((argc (length args)))
    `(let ((dp (make-hash-table :test #'equal)))
       (defun ,name ,args
         (let-if memo (gethash ,@(if (= argc 1)
                                     args
                                     `((list ,@args)))
                               dp)
                 memo
                 (setf (gethash ,@(if (= argc 1)
                                      args
                                      `((list ,@args)))
                                dp)
                       (progn ,@body)))))))

(defparameter n (read-integer))
(defparameter w-max (read-integer))
(defparameter w (make-array n))
(defparameter v (make-array n))
(dotimes (i n)
  (setf #&(w i) (read-integer))
  (setf #&(v i) (read-integer)))

(defdp solve (index weight)
  (cond ((< weight 0) (- inf))
        ((< index 0) 0)
        (t (max (+ (solve (1- index) (- weight #&(w index)))
                   #&(v index))
                (solve (1- index) weight)))))

(format t "~A~%" (solve (1- n) w-max))


#-swank
(unless (member :child-sbcl *features*)
  (quit
   :unix-status
   (process-exit-code
    (run-program *runtime-pathname*
                 `("--control-stack-size" "128MB"
                   "--noinform" "--disable-ldb" "--lose-on-corruption" "--end-runtime-options"
                   "--eval" "(push :child-sbcl *features*)"
                   "--script" ,(namestring *load-pathname*))
                 :output t :error t :input t))))
(defmacro dp (name args memo-size &body body)
  (let ((memo (gensym)))
    `(let ((,memo (make-array ,memo-size :initial-element nil)))
       (defun ,name ,args
         (or (aref ,memo ,@args)
             (setf (aref ,memo ,@args)
                   ,@body))))))

(defun split (x str)
  (let ((pos (search x str))
        (size (length x)))
    (if pos
        (cons (subseq str 0 pos)
              (split x (subseq str (+ pos size))))
        (list str))))

(defun main (n m item)
  (dp f (p w) '(101 100010)
    (if (eq p n) 0
        (apply #'max
               (append (list 0)
                       (loop for i from 0 to 1
                             for nv = (* i (cdr (aref item p)))
                             for nw = (+ w (* i (car (aref item p))))
                             when (<= nw m)
                               collect (+ nv
                                          (f (1+ p)
                                             nw)))))))
  (f 0 0))

(let* ((n (read))
       (m (read))
       (item (make-array (list n) :initial-contents
                         (loop repeat n collect (cons (read) (read))))))
  (princ (main n m item)))


(defun knapsack-p-map-rec-f (things w func)
  (if things
      (let* ((thing (car things))
             (dp-arr (knapsack-p-map-rec-f (cdr things) w func)))
        (if (>= w (car thing))
            (concatenate 'vector (subseq dp-arr 0 (car thing))
                         (map 'vector (lambda (in not-in)
                                        (funcall func not-in (+ in (cdr thing))))
                              dp-arr (subseq dp-arr (car thing))))
            dp-arr))
      (make-array w :initial-element 0)))

(defun knapsack-problem (n w things)
  (let* ((arr (knapsack-p-map-rec-f things (1+ w) #'max)))
    (aref arr (1- (length arr)))))

(let* ((n (read))
       (w (read))
       (things (loop :repeat n :collect (cons (read) (read)))))
  (princ (knapsack-problem n w things)))


(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)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
(in-package :cl-user)

(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)))

(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)

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

(defconstant +mod+ 1000000007)

;;;
;;; Body
;;;

(defun main ()
  (declare #.OPT)
  (let* ((ss (coerce (read-line) 'simple-base-string))
         (slen (length ss))
         (tt (coerce (read-line) 'simple-base-string))
         (tlen (length tt))
         (dp (make-array '(3001 3001) :element-type 'uint16 :initial-element 0))
         (prev-xs (make-array '(3001 3001) :element-type 'uint16 :initial-element 0))
         (prev-ys (make-array '(3001 3001) :element-type 'uint16 :initial-element 0))
         (cs (make-array '(3001 3001) :element-type 'base-char :initial-element #\Nul)))
    (dotimes (x (+ slen 1))
      (dotimes (y (+ tlen 1))
        (unless (= x y 0)
          (let ((value -1)
                (prev-x 0)
                (prev-y 0)
                (char #\Nul))
            (when (and (> x 0) (> (aref dp (- x 1) y) value))
              (setq value (aref dp (- x 1) y)
                    prev-x (- x 1)
                    prev-y y))
            (when (and (> y 0) (> (aref dp x (- y 1)) value))
              (setq value (aref dp x (- y 1))
                    prev-x x
                    prev-y (- y 1)))
            (when (and (> x 0) (> y 0)
                       (char= (aref ss (- x 1)) (aref tt (- y 1)))
                       (> (+ 1 (aref dp (- x 1) (- y 1))) value))
              (setq value (+ 1 (aref dp (- x 1) (- y 1)))
                    prev-x (- x 1)
                    prev-y (- y 1)
                    char (aref ss (- x 1))))
            (setf (aref dp x y) value
                  (aref prev-xs x y) prev-x
                  (aref prev-ys x y) prev-y
                  (aref cs x y) char)))))
    (let ((x slen)
          (y tlen)
          res)
      (loop until (= x y 0)
            unless (char= (aref cs x y) #\Nul)
            do (push (aref cs x y) res)
            do (psetq x (aref prev-xs x y)
                      y (aref prev-ys x y)))
      (map () #'write-char res)
      (terpri))))

#-swank (main)

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

#+swank
(defun io-equal (in-string out-string &key (function #'main) (test #'equal))
  "Passes IN-STRING to *STANDARD-INPUT*, executes FUNCTION, and returns true if
the string output to *STANDARD-OUTPUT* is equal to OUT-STRING."
  (labels ((ensure-last-lf (s)
             (if (eql (uiop:last-char s) #\Linefeed)
                 s
                 (uiop:strcat s uiop:+lf+))))
    (funcall test
             (ensure-last-lf out-string)
             (with-output-to-string (out)
               (let ((*standard-output* out))
                 (with-input-from-string (*standard-input* (ensure-last-lf in-string))
                   (funcall function)))))))

#+swank
(defun get-clipbrd ()
  (with-output-to-string (out)
    (run-program "powershell.exe" '("-Command" "Get-Clipboard") :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* out))
    (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))))))

#+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
   (common-lisp-user::io-equal "axyb
abyxb
"
    "axb
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "aa
xayaz
"
    "aa
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "a
z
"
    "
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "abracadabra
avadakedavra
"
    "aaadara
")))

Score : 100 points

Problem Statement

You are given strings s and t.
Find one longest string that is a subsequence of both s and t.

Notes

A subsequence of a string x is the string obtained by removing zero or more characters from x and concatenating the remaining characters without changing the order.

Constraints

s and t are strings consisting of lowercase English letters.

1 \leq |s|, |t| \leq 3000

Input

Input is given from Standard Input in the following format:

s
t

Output

Print one longest string that is a subsequence of both s and t.
If there are multiple such strings, any of them will be accepted.

Sample Input 1

axyb
abyxb

Sample Output 1

axb

The answer is axb or ayb; either will be accepted.

Sample Input 2

aa
xayaz

Sample Output 2

aa

Sample Input 3

a
z

Sample Output 3

The answer is (an empty string).

Sample Input 4

abracadabra
avadakedavra

Sample Output 4

aaadara


(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)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
(in-package :cl-user)

(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)))

(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)

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

(defconstant +mod+ 1000000007)

;;;
;;; Body
;;;

(defun main ()
  (let* ((ss (coerce (read-line) 'simple-base-string))
         (slen (length ss))
         (tt (coerce (read-line) 'simple-base-string))
         (tlen (length tt))
         (dp (make-array '(3001 3001) :element-type 'uint16 :initial-element 0))
         (prev-xs (make-array '(3001 3001) :element-type 'uint16 :initial-element 0))
         (prev-ys (make-array '(3001 3001) :element-type 'uint16 :initial-element 0))
         (cs (make-array '(3001 3001) :element-type 'base-char :initial-element #\Nul)))
    (dotimes (x (+ slen 1))
      (dotimes (y (+ tlen 1))
        (unless (= x y 0)
          (let ((value -1)
                (prev-x 0)
                (prev-y 0)
                (char #\Nul))
            (when (and (> x 0) (> (aref dp (- x 1) y) value))
              (setq value (aref dp (- x 1) y)
                    prev-x (- x 1)
                    prev-y y))
            (when (and (> y 0) (> (aref dp x (- y 1)) value))
              (setq value (aref dp x (- y 1))
                    prev-x x
                    prev-y (- y 1)))
            (when (and (> x 0) (> y 0)
                       (char= (aref ss (- x 1)) (aref tt (- y 1)))
                       (> (+ 1 (aref dp (- x 1) (- y 1))) value))
              (setq value (+ 1 (aref dp (- x 1) (- y 1)))
                    prev-x (- x 1)
                    prev-y (- y 1)
                    char (aref ss (- x 1))))
            (setf (aref dp x y) value
                  (aref prev-xs x y) prev-x
                  (aref prev-ys x y) prev-y
                  (aref cs x y) char)))))
    (let ((x slen)
          (y tlen)
          res)
      (loop until (= x y 0)
            unless (char= (aref cs x y) #\Nul)
            do (push (aref cs x y) res)
            do (psetq x (aref prev-xs x y)
                      y (aref prev-ys x y)))
      (map () #'write-char res)
      (terpri))))

#-swank (main)

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

#+swank
(defun io-equal (in-string out-string &key (function #'main) (test #'equal))
  "Passes IN-STRING to *STANDARD-INPUT*, executes FUNCTION, and returns true if
the string output to *STANDARD-OUTPUT* is equal to OUT-STRING."
  (labels ((ensure-last-lf (s)
             (if (eql (uiop:last-char s) #\Linefeed)
                 s
                 (uiop:strcat s uiop:+lf+))))
    (funcall test
             (ensure-last-lf out-string)
             (with-output-to-string (out)
               (let ((*standard-output* out))
                 (with-input-from-string (*standard-input* (ensure-last-lf in-string))
                   (funcall function)))))))

#+swank
(defun get-clipbrd ()
  (with-output-to-string (out)
    (run-program "powershell.exe" '("-Command" "Get-Clipboard") :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* out))
    (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))))))

#+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
   (common-lisp-user::io-equal "axyb
abyxb
"
    "axb
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "aa
xayaz
"
    "aa
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "a
z
"
    "
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "abracadabra
avadakedavra
"
    "aaadara
")))


(setq a (string (read)))
(setq al (concatenate 'list a))
(setq b (string (read)))
(setq bl (concatenate 'list b))

(setq n (length al))
(setq m (length bl))
(setq dp (make-array `(,(+ n 1) ,(+ m 1)) :initial-element nil))
(dotimes (i n)
  (dotimes (j m)
    (if (eq (elt al i) (elt bl j))
       (setf (aref dp (+ i 1) (+ j 1))
             (concatenate 'string (aref dp i j) (string (elt al i)))
             )
        (if (> (length (aref dp (+ i 1) j))
               (length (aref dp i (+ j 1)))
               )
            (setf (aref dp (+ i 1) (+ j 1))
                  (aref dp (+ i 1) j))
            (setf (aref dp (+ i 1) (+ j 1))
                  (aref dp i (+ j 1))
                  )
            )
        )
    ))
(format t (string-downcase (aref dp n m


;; -*- coding: utf-8 -*-
(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
           ;; enclose the form with VALUES to avoid being captured by LOOP macro
           #\# #\> (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)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
(declaim (inline read-schar))
(defun read-schar (&optional (stream *standard-input*))
  (declare #-swank (sb-kernel:ansi-stream stream)
           (inline read-byte))
  #+swank (read-char stream nil #\Newline) ; on SLIME
  #-swank (code-char (read-byte stream nil #.(char-code #\Newline))))

(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)))

(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)

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

(defconstant +mod+ 1000000007)

;;;
;;; Body
;;;

(defun main ()
  (declare #.OPT)
  (let* ((h (read))
         (w (read))
         (dp (make-array 1001 :element-type 'uint31 :initial-element 0)))
    (declare (uint16 h w))
    (setf (aref dp 1) 1)
    (dotimes (_ h)
      (loop for x from 1 to w
            do (setf (aref dp x)
                     (if (char= #\. (read-schar))
                         (let ((sum (+ (aref dp x) (aref dp (- x 1)))))
                           (if (>= sum +mod+)
                               (- sum +mod+)
                               sum))
                         0)))
      (read-schar))

    (println (aref dp w))))

#-swank (main)

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

#+swank
(defun io-equal (in-string out-string &key (function #'main) (test #'equal))
  "Passes IN-STRING to *STANDARD-INPUT*, executes FUNCTION, and returns true if
the string output to *STANDARD-OUTPUT* is equal to OUT-STRING."
  (labels ((ensure-last-lf (s)
             (if (eql (uiop:last-char s) #\Linefeed)
                 s
                 (uiop:strcat s uiop:+lf+))))
    (funcall test
             (ensure-last-lf out-string)
             (with-output-to-string (out)
               (let ((*standard-output* out))
                 (with-input-from-string (*standard-input* (ensure-last-lf in-string))
                   (funcall function)))))))

#+swank
(defun get-clipbrd ()
  (with-output-to-string (out)
    ;; (run-program "C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" '("get-clipboard") :output out)
    (run-program "powershell.exe" '("-Command" "Get-Clipboard") :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* out))
    (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))))))

#+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
   (common-lisp-user::io-equal "3 4
...#
.#..
....
"
    "3
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "5 2
..
#.
..
.#
..
"
    "0
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "5 5
..#..
.....
#...#
.....
..#..
"
    "24
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "20 20
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
"
    "345263555
")))


;; -*- coding: utf-8 -*-
(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
           ;; enclose the form with VALUES to avoid being captured by LOOP macro
           #\# #\> (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)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
(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)))

(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)

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

(defconstant +mod+ 1000000007)

;;;
;;; Body
;;;

(defun main ()
  (declare #.OPT)
  (let* ((ss (coerce (read-line) 'simple-base-string))
         (tt (coerce (read-line) 'simple-base-string))
         (slen (length ss))
         (tlen (length tt))
         (dp (make-array (list (+ 1 slen) (+ 1 tlen))
                         :element-type 'uint32
                         :initial-element 0)))
    (declare (uint16 slen tlen))
    (loop for x from 1 to slen
          do (loop for y from 1 to tlen
                   if (char= (aref ss (- x 1)) (aref tt (- y 1)))
                   do (setf (aref dp x y) (+ 1 (aref dp (- x 1) (- y 1))))
                   else if (>= (aref dp (- x 1) y) (aref dp x (- y 1)))
                   do (setf (aref dp x y) (aref dp (- x 1) y))
                   else
                   do (setf (aref dp x y) (aref dp x (- y 1)))))
    (let* ((res (make-string (aref dp slen tlen) :element-type 'base-char))
           (x slen)
           (y tlen)
           (pos (- (length res) 1)))
      (loop while (>= pos 0)
            for len = (aref dp x y)
            if (and (= (+ 1 (aref dp (- x 1) (- y 1))) (aref dp x y))
                    (char= (aref ss (- x 1)) (aref tt (- y 1))))
            do (setf (aref res pos) (aref ss (- x 1))
                     x (- x 1)
                     y (- y 1)
                     pos (- pos 1))
            else if (and (> x 0) (= (aref dp (- x 1) y) (aref dp x y)))
            do (decf x)
            else
            do (decf y))
      (write-line res))))

#-swank (main)

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

#+swank
(defun io-equal (in-string out-string &key (function #'main) (test #'equal))
  "Passes IN-STRING to *STANDARD-INPUT*, executes FUNCTION, and returns true if
the string output to *STANDARD-OUTPUT* is equal to OUT-STRING."
  (labels ((ensure-last-lf (s)
             (if (eql (uiop:last-char s) #\Linefeed)
                 s
                 (uiop:strcat s uiop:+lf+))))
    (funcall test
             (ensure-last-lf out-string)
             (with-output-to-string (out)
               (let ((*standard-output* out))
                 (with-input-from-string (*standard-input* (ensure-last-lf in-string))
                   (funcall function)))))))

#+swank
(defun get-clipbrd ()
  (with-output-to-string (out)
    ;; (run-program "C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" '("get-clipboard") :output out)
    (run-program "powershell.exe" '("-Command" "Get-Clipboard") :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* out))
    (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))))))

#+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
   (common-lisp-user::io-equal "axyb
abyxb
"
    "axb
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "aa
xayaz
"
    "aa
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "a
z
"
    "
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "abracadabra
avadakedavra
"
    "aaadara
")))


;; -*- coding: utf-8 -*-
(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
           ;; enclose the form with VALUES to avoid being captured by LOOP macro
           #\# #\> (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)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
(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)))

(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)

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

(defconstant +mod+ 1000000007)

;;;
;;; Body
;;;

(defun main ()
  (let* ((ss (coerce (read-line) 'simple-base-string))
         (tt (coerce (read-line) 'simple-base-string))
         (slen (length ss))
         (tlen (length tt))
         (dp (make-array (list (+ 1 slen) (+ 1 tlen))
                         :element-type 'uint32
                         :initial-element 0)))
    (declare (uint16 slen tlen))
    (loop for x from 1 to slen
          do (loop for y from 1 to tlen
                   if (char= (aref ss (- x 1)) (aref tt (- y 1)))
                   do (setf (aref dp x y) (+ 1 (aref dp (- x 1) (- y 1))))
                   else if (>= (aref dp (- x 1) y) (aref dp x (- y 1)))
                   do (setf (aref dp x y) (aref dp (- x 1) y))
                   else
                   do (setf (aref dp x y) (aref dp x (- y 1)))))
    #>dp
    (let* ((res (make-string (aref dp slen tlen) :element-type 'base-char))
           (x slen)
           (y tlen)
           (pos (- (length res) 1)))
      (loop while (>= pos 0)
            for len = (aref dp x y)
            if (and (= (+ 1 (aref dp (- x 1) (- y 1))) (aref dp x y))
                    (char= (aref ss (- x 1)) (aref tt (- y 1))))
            do (setf (aref res pos) (aref ss (- x 1))
                     x (- x 1)
                     y (- y 1)
                     pos (- pos 1))
            else if (and (> x 0) (= (aref dp (- x 1) y) (aref dp x y)))
            do (decf x)
            else
            do (assert (and (> y 0) (= (aref dp x (- y 1)) (aref dp x y))))
               (decf y))
      (write-line res))))

#-swank (main)

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

#+swank
(defun io-equal (in-string out-string &key (function #'main) (test #'equal))
  "Passes IN-STRING to *STANDARD-INPUT*, executes FUNCTION, and returns true if
the string output to *STANDARD-OUTPUT* is equal to OUT-STRING."
  (labels ((ensure-last-lf (s)
             (if (eql (uiop:last-char s) #\Linefeed)
                 s
                 (uiop:strcat s uiop:+lf+))))
    (funcall test
             (ensure-last-lf out-string)
             (with-output-to-string (out)
               (let ((*standard-output* out))
                 (with-input-from-string (*standard-input* (ensure-last-lf in-string))
                   (funcall function)))))))

#+swank
(defun get-clipbrd ()
  (with-output-to-string (out)
    ;; (run-program "C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" '("get-clipboard") :output out)
    (run-program "powershell.exe" '("-Command" "Get-Clipboard") :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* out))
    (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))))))

#+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
   (common-lisp-user::io-equal "axyb
abyxb
"
    "axb
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "aa
xayaz
"
    "aa
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "a
z
"
    "
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "abracadabra
avadakedavra
"
    "aaadara
")))