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

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

;; BEGIN_INSERTED_CONTENTS
(declaim (inline map-indices))
(defun map-indices (function max-indices)
  "Applies function to each vector of indices smaller than MAX-INDICES. The
consequence is undefined when the vector is modified in FUNCTION."
  (declare (vector max-indices))
  (let* ((size (length max-indices))
         (indices (make-array size :element-type (array-element-type max-indices))))
    (labels ((recur (pos)
               (declare ((integer 0 #.array-dimension-limit) pos))
               (if (= pos size)
                   (funcall function indices)
                   (dotimes (idx (the (integer 0 #.most-positive-fixnum)
                                      (aref max-indices pos)))
                     (setf (aref indices pos) idx)
                     (recur (+ pos 1))))))
      (recur 0))))

(defmacro do-indices ((var end-indices) &body body)
  "DO-style macro for MAP-INDICES"
  `(block nil (map-indices (lambda (,var) ,@body) ,end-indices)))

;;;
;;; Binomial coefficient with mod
;;; build: O(n)
;;; query: O(1)
;;;

;; TODO: non-global handling

(defconstant +binom-size+ 510000)
(defconstant +binom-mod+ #.(+ (expt 10 9) 7))

(declaim ((simple-array (unsigned-byte 31) (*)) *fact* *fact-inv* *inv*))
(defparameter *fact* (make-array +binom-size+ :element-type '(unsigned-byte 31))
  "table of factorials")
(defparameter *fact-inv* (make-array +binom-size+ :element-type '(unsigned-byte 31))
  "table of inverses of factorials")
(defparameter *inv* (make-array +binom-size+ :element-type '(unsigned-byte 31))
  "table of inverses of non-negative integers")

(defun initialize-binom ()
  (declare (optimize (speed 3) (safety 0)))
  (setf (aref *fact* 0) 1
        (aref *fact* 1) 1
        (aref *fact-inv* 0) 1
        (aref *fact-inv* 1) 1
        (aref *inv* 1) 1)
  (loop for i from 2 below +binom-size+
        do (setf (aref *fact* i) (mod (* i (aref *fact* (- i 1))) +binom-mod+)
                 (aref *inv* i) (- +binom-mod+
                                   (mod (* (aref *inv* (rem +binom-mod+ i))
                                           (floor +binom-mod+ i))
                                        +binom-mod+))
                 (aref *fact-inv* i) (mod (* (aref *inv* i)
                                             (aref *fact-inv* (- i 1)))
                                          +binom-mod+))))

(initialize-binom)

(declaim (inline binom))
(defun binom (n k)
  "Returns nCk."
  (if (or (< n k) (< n 0) (< k 0))
      0
      (mod (* (aref *fact* n)
              (mod (* (aref *fact-inv* k) (aref *fact-inv* (- n k))) +binom-mod+))
           +binom-mod+)))

(declaim (inline perm))
(defun perm (n k)
  "Returns nPk."
  (if (or (< n k) (< n 0) (< k 0))
      0
      (mod (* (aref *fact* n) (aref *fact-inv* (- n k))) +binom-mod+)))

;; TODO: compiler macro or source-transform
(declaim (inline multinomial))
(defun multinomial (&rest ks)
  "Returns the multinomial coefficient K!/k_1!k_2!...k_n! for K = k_1 + k_2 +
... + k_n. K must be equal to or smaller than
MOST-POSITIVE-FIXNUM. (multinomial) returns 1."
  (let ((sum 0)
        (result 1))
    (declare ((integer 0 #.most-positive-fixnum) result sum))
    (dolist (k ks)
      (incf sum k)
      (setq result
            (mod (* result (aref *fact-inv* k)) +binom-mod+)))
    (mod (* result (aref *fact* sum)) +binom-mod+)))

(declaim (inline stirling2))
(defun stirling2 (n k)
  "Returns the stirling number of the second kind S2(n, k). Time complexity is
O(klog(n))."
  (declare ((integer 0 #.most-positive-fixnum) n k))
  (labels ((mod-power (base exp)
             (declare ((integer 0 #.most-positive-fixnum) base exp))
             (loop with res of-type (integer 0 #.most-positive-fixnum) = 1
                   while (> exp 0)
                   when (oddp exp)
                   do (setq res (mod (* res base) +binom-mod+))
                   do (setq base (mod (* base base) +binom-mod+)
                            exp (ash exp -1))
                   finally (return res))))
    (loop with result of-type fixnum = 0
          for i from 0 to k
          for delta = (mod (* (binom k i) (mod-power i n)) +binom-mod+)
          when (evenp (- k i))
          do (incf result delta)
             (when (>= result +binom-mod+)
               (decf result +binom-mod+))
          else
          do (decf result delta)
             (when (< result 0)
               (incf result +binom-mod+))
          finally (return (mod (* result (aref *fact-inv* k)) +binom-mod+)))))

(declaim (inline catalan))
(defun catalan (n)
  "Returns the N-th Catalan number."
  (declare ((integer 0 #.most-positive-fixnum) n))
  (mod (* (aref *fact* (* 2 n))
          (mod (* (aref *fact-inv* (+ n 1))
                  (aref *fact-inv* n))
               +binom-mod+))
       +binom-mod+))

;;;
;;; Arithmetic operations with static modulus
;;;

;; FIXME: Currently MOD* and MOD+ doesn't apply MOD when the number of
;; parameters is one.
(defmacro define-mod-operations (divisor)
  `(progn
     (defun mod* (&rest args)
       (reduce (lambda (x y) (mod (* x y) ,divisor)) args))

     (defun mod+ (&rest args)
       (reduce (lambda (x y) (mod (+ x y) ,divisor)) args))

     #+sbcl
     (eval-when (:compile-toplevel :load-toplevel :execute)
       (locally (declare (muffle-conditions warning))
         (sb-c:define-source-transform mod* (&rest args)
           (if (null args)
               1
               (reduce (lambda (x y) `(mod (* ,x ,y) ,',divisor)) args)))
         (sb-c:define-source-transform mod+ (&rest args)
           (if (null args)
               0
               (reduce (lambda (x y) `(mod (+ ,x ,y) ,',divisor)) args)))))

     (define-modify-macro incfmod (delta)
       (lambda (x y) (mod (+ x y) ,divisor)))

     (define-modify-macro decfmod (delta)
       (lambda (x y) (mod (- x y) ,divisor)))

     (define-modify-macro mulfmod (multiplier)
       (lambda (x y) (mod (* x y) ,divisor)))))


(declaim (inline mod-power))
(defun mod-power (base power modulus)
  "Returns BASE^POWER mod MODULUS. Note: 0^0 = 1.

BASE := integer
POWER, MODULUS := non-negative fixnum"
  (declare ((integer 0 #.most-positive-fixnum) modulus power)
           (integer base))
  (let ((base (mod base modulus))
        (res (mod 1 modulus)))
    (declare ((integer 0 #.most-positive-fixnum) base res))
    (loop while (> power 0)
          when (oddp power)
          do (setq res (mod (* res base) modulus))
          do (setq base (mod (* base base) modulus)
                   power (ash power -1)))
    res))


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

(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 solve-small (n m)
  (let ((res 0)
        (univs (coerce (loop repeat m collect n) 'vector)))
    (do-indices (indices univs)
      (let ((indices (concatenate '(simple-array uint8 (*)) #(0) indices))
            (ins 0)
            (outs 0))
        (loop for i from 1 below (length indices)
              unless (= (aref indices (- i 1)) (aref indices i))
              do (setf (ldb (byte 1 (aref indices i)) ins) 1))
        (loop for i from 0 below (- (length indices) 1)
              unless (= (aref indices i) (aref indices (+ i 1)))
              do (setf (ldb (byte 1 (aref indices i)) outs) 1))
        (when (= (- (ash 1 n) 1) ins outs)
          ;; #>indices
          (incf res))))
    res))
(define-mod-operations +mod+)
(defun calc-total (n m)
  (let ((res 0))
    (loop for i from 0 to n
          do (incfmod res (mod* (mod-power (- n i) (- m 2) +mod+)
                                (binom n i)
                                (if (evenp i) 1 -1))))
    res))

(defun calc-ab (n m x)
  (assert (>= x 2))
  (let ((res 0))
    (loop for i from 0 to (- n 1)
          do (incfmod res (mod* (mod-power (- n 1 i) (- m x 1) +mod+)
                                (binom (- n 1) i)
                                (if (evenp i) 1 -1))))
    res))

(defun calc-c (n m x+y)
  (assert (>= x+y 4))
  (let ((res 0))
    (loop for i from 0 to (- n 2)
          do (incfmod res (mod* (mod-power (- n 2 i) (- m x+y) +mod+)
                                (binom (- n 2) i)
                                (if (evenp i) 1 -1))))
    res))

(defun calc-1 (n m)
  (let ((res 0))
    (loop for i from 0 to (- n 1)
          when (zerop i)
          do (incfmod res (mod-power n (- m 2) +mod+))
          else do (incfmod res (mod* (mod-power (- n i) (- m 2) +mod+)
                                     (binom (- n 1) i)
                                     (if (evenp i) 1 -1))))
    res))

;; (defun solve (n m)
;;   (let* ((m (+ m 1))
;;          (factor (calc-total n m)))
;;     (loop for x from 2 to (- m 1)
;;           do (decfmod factor (* 2 (calc-ab n m x))))
;;     (loop for sum from 4 to m
;;           do (incfmod factor #>(mod* (- sum 3) (calc-c n m sum))) )
;;     #>factor
;;     (let ((res (mod+ (mod* factor (- n 1))
;;                      (calc-1 n m))))
;;       res)))

;; (defun solve* (n m)
;;   (let* ((m (+ m 1))
;;          (res 0))
;;     (loop for len from 2 to m
;;           for factor = #>(calc-1 n len)
;;           do (incfmod res (mod* factor (mod-power (- n 1) (- m len) +mod+))))
;;     res))

(defun solve (n m)
  (let ((dp (make-array (list (+ m 1) (+ n 1) (+ n 1))
                        :element-type 'uint31
                        :initial-element 0)))
    (setf (aref dp 0 1 0) 1)
    (dotimes (x m)
      (dotimes (y (+ n 1))
        (dotimes (z (+ n 1))
          (unless (zerop (aref dp x y z))
            (incfmod (aref dp (+ x 1) (+ y z) 0)
                     (mod* (aref dp x y z) y))
            (incfmod (aref dp (+ x 1) y (+ z 1))
                     (mod* (aref dp x y z) (- n y z)))
            (incfmod (aref dp (+ x 1) y z)
                     (mod* (aref dp x y z) z))))))
    ;; #>dp
    (aref dp m n 0)))
(defun main ()
  (let* ((n (read))
         (m (read)))
    (println (solve n m))))

#-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)
    #+os-windows (run-program "powershell.exe" '("-Command" "Get-Clipboard") :output out :search t)
    #+os-unix (run-program "xsel" '("-b" "-o") :output out :search t)))

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

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

null: run #'MAIN using the text on clipboard as input.
string: run #'MAIN using the string as input.
symbol: alias of FIVEAM:RUN!.
pathname: run #'MAIN using the text file as input."
  (let ((*standard-output* 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)))


Measured memory_bytes: 85244