Buggy python submission (verdict: Runtime Error):
"""
14:07-
"""
import bisect
import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(2147483647)
INF = float("inf")

N, M = list(map(int, sys.stdin.readline().split()))
A = list(map(int, sys.stdin.readline().split()))
B = list(map(int, sys.stdin.readline().split()))

MOD = 10 ** 9 + 7

A.sort()
B.sort()

if any([a == b for a, b in zip(A[:-1], A[1:])]) or any([a == b for a, b in zip(B[:-1], B[1:])]):
    # 同じのが複数ある
    print(0)
    exit()
if max(A) > N * M or max(B) > N * M:
    # 最大値が大きすぎ
    print(0)
    exit()

remains = 0
fixed = 0
ans = 1
for k in range(1, N * M + 1)[::-1]:
    # k が入る場所どこ？
    top = bisect.bisect_left(A, k)
    left = bisect.bisect_left(B, k)
    if A[top] == k and B[left] == k:
        # このマスに入れるしかない
        pattern = 1
        fixed += 1
    elif A[top] == k:
        # この行のどっか
        pattern = len(B) - left
        fixed += 1
    elif B[left] == k:
        # この列のどっか
        pattern = len(A) - top
        fixed += 1
    else:
        # どこでも OK
        couho = (len(A) - top) * (len(B) - left)
        pattern = couho - fixed
        fixed += 1
    ans *= pattern
    ans %= MOD
print(ans)


Fixed submission:
"""
14:07-
"""
import bisect
import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(2147483647)
INF = float("inf")

N, M = list(map(int, sys.stdin.readline().split()))
A = list(map(int, sys.stdin.readline().split()))
B = list(map(int, sys.stdin.readline().split()))

MOD = 10 ** 9 + 7

A.sort()
B.sort()

if any([a == b for a, b in zip(A[:-1], A[1:])]) or any([a == b for a, b in zip(B[:-1], B[1:])]):
    # 同じのが複数ある
    print(0)
    exit()
if max(A) != N * M or max(B) != N * M:
    # 最大値がおかしい
    print(0)
    exit()

fixed = 0
ans = 1
top = len(A) - 1
left = len(B) - 1
for k in range(1, N * M + 1)[::-1]:
    # k が入る場所どこ？
    while top - 1 >= 0 and A[top - 1] >= k:
        top -= 1
    while left - 1 >= 0 and B[left - 1] >= k:
        left -= 1
    top = bisect.bisect_left(A, k)
    left = bisect.bisect_left(B, k)
    if A[top] == k and B[left] == k:
        # このマスに入れるしかない
        pattern = 1
        fixed += 1
    elif A[top] == k:
        # この行のどっか
        pattern = len(B) - left
        fixed += 1
    elif B[left] == k:
        # この列のどっか
        pattern = len(A) - top
        fixed += 1
    else:
        # どこでも OK
        pattern = (len(A) - top) * (len(B) - left) - fixed
        fixed += 1
    ans *= pattern
    ans %= MOD
print(ans)

Buggy python submission (verdict: Runtime Error):
"""
14:07-
"""
import os
import sys

import numpy as np

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(2147483647)
INF = float("inf")

N, M = list(map(int, sys.stdin.readline().split()))
A = list(map(int, sys.stdin.readline().split()))
B = list(map(int, sys.stdin.readline().split()))

MOD = 10 ** 9 + 7

A = np.array(A)
B = np.array(B)
A.sort()
B.sort()
if (np.diff(A) == 0).sum() > 0 or (np.diff(B) == 0).sum() > 0:
    # 同じのが複数ある
    print(0)
    exit()

remains = 0
fixed = 0
ans = 1
for k in range(1, N * M + 1)[::-1]:
    # k が入る場所どこ？
    top = np.searchsorted(A, k)
    left = np.searchsorted(B, k)
    if A[top] == k and B[left] == k:
        # このマスに入れるしかない
        pattern = 1
        fixed += 1
    elif A[top] == k:
        # この行のどっか
        pattern = len(B) - left
        fixed += 1
    elif B[left] == k:
        # この列のどっか
        pattern = len(A) - top
        fixed += 1
    else:
        # どこでも OK
        couho = (len(A) - top) * (len(B) - left)
        pattern = couho - fixed
        fixed += 1
    ans *= pattern
    ans %= MOD
print(ans)


Fixed submission:
"""
14:07-
"""
import bisect
import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(2147483647)
INF = float("inf")

N, M = list(map(int, sys.stdin.readline().split()))
A = list(map(int, sys.stdin.readline().split()))
B = list(map(int, sys.stdin.readline().split()))

MOD = 10 ** 9 + 7

A.sort()
B.sort()

if any([a == b for a, b in zip(A[:-1], A[1:])]) or any([a == b for a, b in zip(B[:-1], B[1:])]):
    # 同じのが複数ある
    print(0)
    exit()
if max(A) != N * M or max(B) != N * M:
    # 最大値がおかしい
    print(0)
    exit()

fixed = 0
ans = 1
top = len(A) - 1
left = len(B) - 1
for k in range(1, N * M + 1)[::-1]:
    # k が入る場所どこ？
    while top - 1 >= 0 and A[top - 1] >= k:
        top -= 1
    while left - 1 >= 0 and B[left - 1] >= k:
        left -= 1
    top = bisect.bisect_left(A, k)
    left = bisect.bisect_left(B, k)
    if A[top] == k and B[left] == k:
        # このマスに入れるしかない
        pattern = 1
        fixed += 1
    elif A[top] == k:
        # この行のどっか
        pattern = len(B) - left
        fixed += 1
    elif B[left] == k:
        # この列のどっか
        pattern = len(A) - top
        fixed += 1
    else:
        # どこでも OK
        pattern = (len(A) - top) * (len(B) - left) - fixed
        fixed += 1
    ans *= pattern
    ans %= MOD
print(ans)