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

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

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

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

;; Hauptteil

(defconstant +magic+ #.(+ (expt 10 9) 7))
(defun main ()
  (declare #.OPT)
  (let* ((n (read))
         (m (read))
         (nm (* n m))
         (as (make-array n :element-type 'uint32))
         (bs (make-array m :element-type 'uint32))
         (x<=as (make-array (1+ nm) :element-type 'uint32))
         (x<=bs (make-array (1+ nm) :element-type 'uint32))
         (a-set (make-hash-table :test #'eql))
         (b-set (make-hash-table :test #'eql)))
    (declare (uint15 n m))
    (split-ints-into-vector (read-line) as)
    (split-ints-into-vector (read-line) bs)
    (setf as (sort as #'<))
    (setf bs (sort bs #'<))
    (nlet recurse ((x 0) (a-idx 0))
      (declare (uint32 x a-idx))
      (when (< a-idx n)
        (loop for x from x below (length x<=as)
              while (<= x (aref as a-idx))
              do (setf (aref x<=as x) (- n a-idx))
              finally (return (recurse x (+ a-idx 1))))))
    (nlet recurse ((x 0) (b-idx 0))
      (declare (uint32 x b-idx))
      (when (< b-idx m)
        (loop for x from x below (length x<=bs)
              while (<= x (aref bs b-idx))
              do (setf (aref x<=bs x) (- m b-idx))
              finally (return (recurse x (+ b-idx 1))))))
    (dotimes (i n)
      (setf (gethash (aref as i) a-set) t))
    (dotimes (j m)
      (setf (gethash (aref bs j) b-set) t))
    (dotimes (i (- n 1))
      (when (= (aref as i) (aref as (+ i 1)))
        (println 0)
        (return-from main)))
    (dotimes (j (- m 1))
      (when (= (aref bs j) (aref bs (+ j 1)))
        (println 0)
        (return-from main)))
    (loop with res of-type uint32 = 1
          for x from nm downto 1
          do (if (gethash x a-set)
                 (unless (gethash x b-set)
                   (setf res (mod (* res (aref x<=bs x)) +magic+)))
                 (if (gethash x b-set)
                     (setf res (mod (* res (aref x<=as x)) +magic+))
                     (setf res (mod (* res
                                       (the uint32
                                            (- (mod (* (aref x<=as x) (aref x<=bs x))
                                                    +magic+)
                                               (- nm x))))
                                    +magic+))))
          finally (println res))))

#-swank(main)


Measured memory_bytes: 39008