;; -*- coding: utf-8 -*-
(eval-when (:compile-toplevel :load-toplevel :execute)
  (defparameter OPT
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0)))
  #+swank (ql:quickload '(:cl-debug-print :fiveam))
  #-swank (set-dispatch-macro-character #\# #\> (lambda (s c p) (declare (ignore c p)) (read s nil (values) t))))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
(declaim (inline bisect-left))
(defun bisect-left (target value &key (start 0) end (order #'<) (key #'identity))
  "TARGET := vector | function (taking an integer argument)
ORDER := strict order

Analogue of lower_bound of C++ or bisect_left of Python: Returns the smallest
index (or input) i that fulfills TARGET[i] >= VALUE, where '>=' is the
complement of ORDER. In other words, this function returns the leftmost index at
which VALUE can be inserted with keeping the order. Therefore, TARGET must be
monotonically non-decreasing with respect to ORDER.

This function returns END if VALUE exceeds TARGET[END-1]. Note that the range
[START, END) is half-open. END must be explicitly specified if TARGET is
function. KEY is applied to each element of TARGET before comparison."
  (declare (function key order)
           (integer start)
           ((or null integer) end))
  (macrolet
      ((body (accessor &optional declaration)
         `(progn
            (assert (<= start end))
            (if (= start end) end
                (labels
                    ((%bisect-left (left ok)
                       ;; TARGET[OK] >= VALUE always holds (assuming
                       ;; TARGET[END] = +infinity)
                       ,@(list declaration)
                       (let ((mid (ash (+ left ok) -1)))
                         (if (= mid left)
                             (if (funcall order (funcall key (,accessor target left)) value)
                                 ok
                                 left)
                             (if (funcall order (funcall key (,accessor target mid)) value)
                                 (%bisect-left mid ok)
                                 (%bisect-left left mid))))))
                  (%bisect-left start end))))))
    (etypecase target
      (vector
       (let ((end (or end (length target))))
         (body aref (declare ((integer 0 #.most-positive-fixnum) left ok)))))
      (function
       (assert end () "Requires END argument if TARGET is a function.")
       (body funcall)))))

(declaim (inline bisect-right))
(defun bisect-right (target value &key (start 0) end (order #'<) (key #'identity))
  "TARGET := vector | function (taking an integer argument)
ORDER := strict order

Analogue of upper_bound of C++ or bisect_right of Python: Returns the smallest
index (or input) i that fulfills TARGET[i] > VALUE. In other words, this
function returns the rightmost index at which VALUE can be inserted with keeping
the order. TARGET must be monotonically non-decreasing with respect to ORDER.

This function returns END if VALUE >= TARGET[END-1]. Note that the range [START,
END) is half-open. END must be explicitly specified if TARGET is function. KEY
is applied to each element of TARGET before comparison."
  (declare (function key order)
           (integer start)
           ((or null integer) end))
  (macrolet
      ((body (accessor &optional declaration)
         `(progn
            (assert (<= start end))
            (if (= start end)
                end
                (labels
                    ((%bisect-right (left ok)
                       ;; TARGET[OK] > VALUE always holds (assuming
                       ;; TARGET[END] = +infinity)
                       ,@(list declaration)
                       (let ((mid (ash (+ left ok) -1)))
                         (if (= mid left)
                             (if (funcall order value (funcall key (,accessor target left)))
                                 left
                                 ok)
                             (if (funcall order value (funcall key (,accessor target mid)))
                                 (%bisect-right left mid)
                                 (%bisect-right mid ok))))))
                  
                  (%bisect-right start end))))))
    (etypecase target
      (vector
       (when (null end)
         (setf end (length target)))
       (body aref (declare ((integer 0 #.most-positive-fixnum) left ok))))
      (function
       (assert end () "Requires END argument if TARGET is a function.")
       (body funcall)))))

(declaim (ftype (function * (values (vector (integer 0 #.most-positive-fixnum)) &optional))
                enum-divisors))
(defun enum-divisors (x)
  "Enumerates all the divisors of X in O(sqrt(X)). Note that the resultant
vector is NOT sorted."
  (declare (optimize (speed 3))
           ((integer 0 #.most-positive-fixnum) x))
  (let* ((sqrt (isqrt x))
         (res (make-array (isqrt sqrt) ; FIXME: sets the initial size to x^1/4
                          :element-type '(integer 0 #.most-positive-fixnum)
                          :fill-pointer 0)))
    (loop for i from 1 to sqrt
          do (multiple-value-bind (quot rem) (floor x i)
               (when (zerop rem)
                 (vector-push-extend i res)
                 (unless (= i quot)
                   (vector-push-extend quot res)))))
    res))

;; Below is the variant that returns a sorted list.
;; (defun enum-divisors (n)
;;   "Returns the increasing list of all the divisors of N."
;;   (declare (optimize (speed 3))
;;            ((integer 1 #.most-positive-fixnum) n))
;;   (if (= n 1)
;;       (list 1)
;;       (let* ((sqrt (isqrt n))
;;              (result (list 1)))
;;         (labels ((%enum (i first-half second-half)
;;                    (declare ((integer 1 #.most-positive-fixnum) i))
;;                    (cond ((or (< i sqrt)
;;                               (and (= i sqrt) (/= (* sqrt sqrt) n)))
;;                           (multiple-value-bind (quot rem) (floor n i)
;;                             (if (zerop rem)
;;                                 (progn
;;                                   (setf (cdr first-half) (list i))
;;                                   (setf second-half (cons quot second-half))
;;                                   (%enum (1+ i) (cdr first-half) second-half))
;;                                 (%enum (1+ i) first-half second-half))))
;;                          ((= i sqrt) ; N is a square number here
;;                           (setf (cdr first-half) (cons i second-half)))
;;                          (t ; (> i sqrt)
;;                           (setf (cdr first-half) second-half)))))
;;           (%enum 2 result (list n))
;;           result))))

(defun make-divisors-table (sup)
  "Returns a vector of length SUP whose each cell, vector[INDEX], is the
increasing list of every divisor of INDEX. Note that vector[0] = NIL."
  (declare ((integer 0 #.most-positive-fixnum) sup))
  (let ((result (make-array sup :element-type 'list))
        (tails (make-array sup :element-type 'list))) ; preserves the last cons
    (declare (optimize (speed 3) (safety 0)))
    (loop for i from 1 below sup
          for cell = (list 1)
          do (setf (aref result i) cell
                   (aref tails i) cell))
    (when (>= sup 1)
      (setf (aref result 0) nil))
    (loop for divisor from 2 below sup
          do (loop for number from divisor below sup by divisor
                   do (setf (cdr (aref tails number)) (list divisor))
                      (setf (aref tails number) (cdr (aref tails number)))))
    result))

(declaim (ftype (function * (values fixnum &optional)) read-fixnum))
(defun read-fixnum (&optional (in *standard-input*))
  (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 #\-))
                                  (setf 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))))))))

(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 feasible-p (div as)
  (let ((as (copy-seq as))
        (n (length as)))
    (dotimes (i n)
      (setf (aref as i) (mod (aref as i) div)))
    (setf as (sort as #'<))
    (let ((end (- n 1))
          (res 0))
      (dotimes (i n)
        (unless (< i end)
          (return))
        (let ((a (aref as i)))
          (incf res a)
          (loop (unless (< i end)
                  (return))
                (when (= a 0)
                  (return))
                (if (<= (+ (aref as end) a) div)
                    (let ((delta a))
                      (setf (aref as end) (+ (aref as end) delta)
                            a 0))
                    (let ((delta (- div (aref as end))))
                      (setf (aref as end) div
                            a (- a delta))
                      (decf end))))))
      res)))

(defun main ()
  (let* ((n (read))
         (k (read))
         (as (make-array n :element-type 'uint32))
         (sum 0))
    (dotimes (i n)
      (setf (aref as i) (read-fixnum))
      (incf sum (aref as i)))
    (let ((divs (enum-divisors sum)))
      (setf divs (sort divs #'>))
      (loop for d across divs
            when (<= (feasible-p d as) k)
            do (println d)
               (return-from main)))))

#-swank (main)


;; For Test
#+swank
(defun io-equal (in-string out-string &optional (func #'main))
  "Passes IN-STRING to *STANDARD-INPUT*, executes FUNC, 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+))))
    (equal (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 func)))))))

#+swank
(defun get-clipbrd ()
  (with-output-to-string (out)
    (run-program "C:/msys64/usr/bin/cat.exe" '("/dev/clipboard") :output out)))

#+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*))
  (let ((*standard-output* out))
    (etypecase thing
      (null ; Runs #'MAIN with the string on clipboard
       (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 ; Runs #'MAIN with the string in a text file
       (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 "2 3
8 20
"
    "7
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "2 10
3 5
"
    "8
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "4 5
10 1 2 22
"
    "7
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "8 7
1 7 5 6 8 2 6 5
"
    "5
")))


Measured memory_bytes: 25064