CodeEff/ECCO huggingface dataset:
# Original solution
import sys
from bisect import bisect_left

sys.setrecursionlimit(10 ** 7)
input = sys.stdin.readline
f_inf = float('inf')
mod = 10 ** 9 + 7


def resolve():
    n, m = list(map(int, input().split()))
    A = list(map(int, input().split()))
    B = list(map(int, input().split()))
    if len(A) != len(set(A)) or len(B) != len(set(B)):
        print((0))
        exit()
    A.sort()
    B.sort()
    As = set(A)
    Bs = set(B)
    res = 1
    for x in reversed(list(range(1, n * m + 1))):
        if x in As and x in Bs:
            continue
        elif x in A:
            res *= m - bisect_left(B, x)
        elif x in B:
            res *= n - bisect_left(A, x)
        else:
            s = m - bisect_left(B, x)
            t = n - bisect_left(A, x)
            res *= s * t - (n * m - x)
        res %= mod
    print(res)


if __name__ == '__main__':
    resolve()


# Optimized solution
import sys
from bisect import bisect_left

sys.setrecursionlimit(10 ** 7)
input = sys.stdin.readline
f_inf = float('inf')
mod = 10 ** 9 + 7


def resolve():
    n, m = list(map(int, input().split()))
    A = list(map(int, input().split()))
    B = list(map(int, input().split()))
    if len(A) != len(set(A)) or len(B) != len(set(B)):
        print((0))
        exit()
    A.sort()
    B.sort()
    As = set(A)
    Bs = set(B)
    res = 1
    for x in reversed(list(range(1, n * m + 1))):
        if x in As and x in Bs:
            continue
        elif x in As:
            res *= m - bisect_left(B, x)
        elif x in Bs:
            res *= n - bisect_left(A, x)
        else:
            s = m - bisect_left(B, x)
            t = n - bisect_left(A, x)
            res *= s * t - (n * m - x)
        res %= mod
    print(res)


if __name__ == '__main__':
    resolve()
# Original solution
from collections import Counter

N,M = list(map(int,input().split()))
A = sorted(list(map(int,input().split())),reverse=True)
B = sorted(list(map(int,input().split())),reverse=True)
mod = pow(10,9)+7

n,m = 0,0
ans = 1

def istwo(L):
    if len(list([x for x in list(Counter(L).values()) if x>1]))>0:
        return True
    else:
        return False

if istwo(A) or istwo(B):
    print((0))
else:
    for i in range(1,(N*M)+1)[::-1]:
        if n<N and i<=A[n]:n+=1
        if m<M and i<=B[m]:m+=1
        if i in A and i in B:
            ans = ans%mod
        elif i in A:
            ans = (ans*(m))%mod
        elif i in B:
            ans = (ans*(n))%mod
        else:
            ans = (ans*(n*m-(N*M-i)))%mod
        #print(i,n,m,ans)
    print(ans)

# Optimized solution
from collections import Counter

N,M = list(map(int,input().split()))
A = sorted(list(map(int,input().split())),reverse=True)
B = sorted(list(map(int,input().split())),reverse=True)
mod = pow(10,9)+7

n,m = 0,0
ans = 1

def istwo(L):
    if len(list([x for x in list(Counter(L).values()) if x>1]))>0:
        return True
    else:
        return False

if istwo(A) or istwo(B):
    print((0))
else:
    for i in range(1,(N*M)+1)[::-1]:
        if n<N and i<=A[n]:n+=1
        if m<M and i<=B[m]:m+=1
        if n>0 and m>0 and i == A[n-1] and i == B[m-1]:
            ans = ans%mod
        elif n>0 and i == A[n-1]:
            ans = (ans*(m))%mod
        elif m>0 and i == B[m-1]:
            ans = (ans*(n))%mod
        else:
            ans = (ans*(n*m-(N*M-i)))%mod
        #print(i,n,A[n-1],m,B[m-1],ans)
    print(ans)
# Original solution
import bisect
MOD = 10**9+7
N,M = list(map(int,input().split()))
A = sorted(list(map(int,input().split())))
B = sorted(list(map(int,input().split())))
a = set(A)
b = set(B)
check = True
if len(a) != N or len(b) != M:
    check = False
ans = 1
for num in range(N*M,0,-1):
    tmp = 0
    if num in A and num in B: continue
    elif num in A:
        tmp = M - bisect.bisect_left(B,num)
    elif num in B:
        tmp = N - bisect.bisect_left(A,num)
    else:
        x = bisect.bisect_left(A,num)
        y = bisect.bisect_left(B,num)
        tmp = (N-x)*(M-y) - (M*N-num) 
    
    if tmp < 0 or check == False:
        check = False
        break
    ans *= tmp
    ans %= MOD

print((ans if check else 0))

# Optimized solution
import bisect
MOD = 10**9+7
N,M = list(map(int,input().split()))
A = sorted(list(map(int,input().split())))
B = sorted(list(map(int,input().split())))
a = set(A)
b = set(B)
check = True
if len(a) != N or len(b) != M:
    check = False
ans = 1
for num in range(N*M,0,-1):
    tmp = 0
    if num in a and num in b: continue
    elif num in a:
        tmp = M - bisect.bisect_left(B,num)
    elif num in b:
        tmp = N - bisect.bisect_left(A,num)
    else:
        x = bisect.bisect_left(A,num)
        y = bisect.bisect_left(B,num)
        tmp = (N-x)*(M-y) - (M*N-num) 
    
    if tmp < 0 or check == False:
        check = False
        break
    ans *= tmp
    ans %= MOD

print((ans if check else 0))
# Original solution
N,M = list(map(int,input().split()))
A = list(map(int,input().split()))
B = list(map(int,input().split()))
a = [0 for i in range(N*M+1)]
b = [0 for i in range(N*M+1)]
da = [0 for i in range(N*M+1)]
db = [0 for i in range(N*M+1)]
mod = 10**9+7
for i in range(N):
    a[A[i]] += 1
    if da[A[i]] == 1:
        print((0))
        quit()
    da[A[i]] += 1
for i in range(M):
    b[B[i]] += 1
    if db[B[i]] == 1:
        print((0))
        quit()
    db[B[i]] += 1
for i in range(1,N*M+1):
    a[-i-1] += a[-i]
    b[-i-1] += b[-i]
ans = 1
for i in range(N*M):
    f = 0
    g = 0
    x = N*M - i
    y = i
    if da[x] == 1:
        f = 1
    if db[x] == 1:
        g = 1
    z = 1
    if f == 0:
        z *= a[x]
    if g == 0:
        z *= b[x]
    if f+g == 0:
        z -= i
    if z <= 0:
        print((0))
        quit()
    else:
        ans *= z%mod
print((ans%mod))

# Optimized solution
N,M = list(map(int,input().split()))
A = list(map(int,input().split()))
B = list(map(int,input().split()))
a = [0 for i in range(N*M+1)]
b = [0 for i in range(N*M+1)]
da = [0 for i in range(N*M+1)]
db = [0 for i in range(N*M+1)]
mod = 10**9+7
for i in range(N):
    a[A[i]] += 1
    if da[A[i]] == 1:
        print((0))
        quit()
    da[A[i]] += 1
for i in range(M):
    b[B[i]] += 1
    if db[B[i]] == 1:
        print((0))
        quit()
    db[B[i]] += 1
for i in range(1,N*M+1):
    a[-i-1] += a[-i]
    b[-i-1] += b[-i]
ans = 1
for i in range(N*M):
    f = 0
    g = 0
    x = N*M - i
    y = i
    if da[x] == 1:
        f = 1
    if db[x] == 1:
        g = 1
    z = 1
    if f == 0:
        z = z*a[x]%mod
    if g == 0:
        z = z*b[x]%mod
    if f+g == 0:
        z -= i
    if z <= 0:
        print((0))
        quit()
    else:
        ans = ans*z%mod
print((ans%mod))
# Original solution
n,m = list(map(int,input().split()))
a = list(map(int,input().split()))
b = list(map(int,input().split()))

ans = 1
cnta = 0
cntb = 0
mod = 10**9+7
for num in range(n*m,0,-1):
    if num in a and num in b:
        cnta += 1
        cntb += 1
        cnta%=mod
        cntb%=mod
    elif num in a:
        ans *= cntb
        ans %= mod
        cnta += 1
    elif num in b:
        ans *= cnta
        ans %= mod
        cntb += 1
    else:
        ans *= (cnta*cntb - (n*m - num))%mod
        ans %= mod

print(ans)

# Optimized solution
n,m = list(map(int,input().split()))
a = list(map(int,input().split()))
b = list(map(int,input().split()))
A=set(a);B=set(b)
ans = 1
cnta = 0
cntb = 0
mod = 10**9+7
for num in range(n*m,0,-1):
    if num in A and num in B:
        cnta += 1
        cntb += 1
    elif num in A:
        ans *= cntb
        cnta += 1
    elif num in B:
        ans *= cnta
        cntb += 1
    else:
        ans *= (cnta*cntb - (n*m - num))%mod
    ans %= mod
print(ans)
# Original solution
import sys

# %%

n, m = list(map(int, sys.stdin.readline().split()))
ary = sorted(list(map(int, sys.stdin.readline().split())), reverse=True)
bry = sorted(list(map(int, sys.stdin.readline().split())), reverse=True)
mod = 10 ** 9 + 7

# %%

if len(set(ary)) != len(ary) or len(set(bry)) != len(bry):
    print((0))

else:
    ary.append(0)
    bry.append(0)

    cnt = 1
    i = 0
    j = 0
    for num in range(n * m, 0, -1):

        if (num == ary[i]) & (num == bry[j]):
            i += 1
            j += 1

        elif (num == ary[i]) ^ (num == bry[j]):
            if num == ary[i]:
                cnt *= len(bry[:j])
                i += 1
            else:
                cnt *= len(ary[:i])
                j += 1

        else:
            na = len(ary[:i])
            nb = len(bry[:j])
            cnt *= (na * nb - (n * m - num))

        cnt = cnt % mod

    print((cnt % mod))


# Optimized solution
import sys

# %%

n, m = list(map(int, sys.stdin.readline().split()))
ary = sorted(list(map(int, sys.stdin.readline().split())), reverse=True)
bry = sorted(list(map(int, sys.stdin.readline().split())), reverse=True)
mod = 10 ** 9 + 7

# %%

if len(set(ary)) != len(ary) or len(set(bry)) != len(bry):
    print((0))

else:
    ary.append(0)
    bry.append(0)

    cnt = 1
    i = 0
    j = 0
    for num in range(n * m, 0, -1):

        if (num == ary[i]) and (num == bry[j]):
            i += 1
            j += 1

        elif (num == ary[i]) or (num == bry[j]):
            if num == ary[i]:
                cnt *= len(bry[:j])
                i += 1
            else:
                cnt *= len(ary[:i])
                j += 1

        else:
            # na = len(ary[:i])
            # nb = len(bry[:j])
            cnt *= (i * j - (n * m - num))

        cnt = cnt % mod

    print(cnt)
# Original solution
import sys

# %%

n, m = list(map(int, sys.stdin.readline().split()))
ary = sorted(list(map(int, sys.stdin.readline().split())), reverse=True)
bry = sorted(list(map(int, sys.stdin.readline().split())), reverse=True)
mod = 10 ** 9 + 7

# %%

if len(set(ary)) != len(ary) or len(set(bry)) != len(bry):
    print((0))

else:
    ary.append(0)
    bry.append(0)

    cnt = 1
    i = 0
    j = 0
    for num in range(n * m, 0, -1):

        if (num == ary[i]) & (num == bry[j]):
            i += 1
            j += 1

        elif (num == ary[i]) ^ (num == bry[j]):
            if num == ary[i]:
                cnt *= len(bry[:j])
                i += 1
            else:
                cnt *= len(ary[:i])
                j += 1

        else:
            na = len(ary[:i])
            nb = len(bry[:j])
            cnt *= (na * nb - (n * m - num))

        cnt = cnt % mod

    print(cnt)


# Optimized solution
import sys

# %%

n, m = list(map(int, sys.stdin.readline().split()))
ary = sorted(list(map(int, sys.stdin.readline().split())), reverse=True)
bry = sorted(list(map(int, sys.stdin.readline().split())), reverse=True)
mod = 10 ** 9 + 7

# %%

if len(set(ary)) != len(ary) or len(set(bry)) != len(bry):
    print((0))

else:
    ary.append(0)
    bry.append(0)

    cnt = 1
    i = 0
    j = 0
    for num in range(n * m, 0, -1):

        if (num == ary[i]) & (num == bry[j]):
            i += 1
            j += 1

        elif (num == ary[i]) ^ (num == bry[j]):
            if num == ary[i]:
                cnt *= j
                i += 1
            else:
                cnt *= i
                j += 1

        else:
            cnt *= (i * j - (n * m - num))

        cnt = cnt % mod

    print(cnt)
# Original solution
H,W=list(map(int,input().split()))
hlen = list(map(int,input().split()))
wlen =	list(map(int,input().split()))
hlen.sort(reverse=True)
wlen.sort(reverse=True)
hhlen =[0 for _ in range(H*W+1)]
wwlen =[0 for _ in range(H*W+1)]
for x,xx in zip([hlen,wlen],[hhlen,wwlen]):
	c = 1
	for y in x:
		if xx[y] != 0:
			print((0))
			exit()
		else:
			xx[y] = c


def Count(x,l):
	ret = 0
	while l[ret] > x :
		ret += 1
		if ret == len(l):
			break
	return ret	

m = max(hlen[0],wlen[0])
count = 1
for num in range(1,H*W+1)[::-1]:
	if hhlen[num] and wwlen[num]:
		count *= 1
	elif hhlen[num]:
		count *= Count(num,wlen)
	elif wwlen[num]:
		count *= Count(num,hlen)
	else:
		count *= Count(num,hlen)*Count(num,wlen) - (m-num)
	#print(num,flagh,flagw,count)
	count %= (10**9+7)
print((count % (10**9+7)))

# Optimized solution
H,W=list(map(int,input().split()))
hlen = list(map(int,input().split()))
wlen =	list(map(int,input().split()))
hlen.sort(reverse=True)
wlen.sort(reverse=True)
hlen.append(0)
wlen.append(0)

m = H*W
count = 1
h=0
w=0
for num in range(1,H*W+1)[::-1]:
	if hlen[h] == num and wlen[w] == num:
		count *= 1
		h += 1
		w += 1
	elif hlen[h] == num:
		count *= w
		h += 1
	elif wlen[w] == num:
		count *= h
		w += 1
	else:
		count *= h*w - (m-num)
	#print(num,flagh,flagw,count)
	count %= (10**9+7)
print(count)
# Original solution
N, M = [int(x) for x in input().split()]
A = [int(x) for x in input().split()]
B = [int(x) for x in input().split()]

ret = 1
MOD = 10 ** 9 + 7

from collections import Counter
import sys

ca = Counter(A)
cb = Counter(B)

if ca.most_common(1)[0][1] >= 2 or cb.most_common(1)[0][1] >= 2:
    print((0))
    sys.exit(0)

A.sort()
B.sort()

import bisect


def index(a, x):
    'Locate the leftmost value exactly equal to x'
    i = bisect.bisect_left(a, x)
    if i != len(a) and a[i] == x:
        return i
    return -1


for n in range(N * M, 0, -1):
    a = index(A, n)
    b = index(B, n)
    cntA = len(A) - bisect.bisect_right(A, n)
    cntB = len(B) - bisect.bisect_right(B, n)

    # 両方みつけた
    if a != -1 and b != -1:
        pass

    # Bの方だけ見つけた
    elif a == -1 and b != -1:
        ret *= cntA

    # Aの方だけ見つけた
    elif a != -1 and b == -1:
        ret *= cntB

    # 両方なかった
    else:
        ret *= (cntA * cntB - (N * M - n))
    ret = ret % MOD

print(ret)


# Optimized solution
N, M = [int(x) for x in input().split()]
A = [int(x) for x in input().split()]
B = [int(x) for x in input().split()]

ret = 1
MOD = 10 ** 9 + 7

A.sort(reverse=True)
B.sort(reverse=True)

aidx = bidx = 0

for n in range(N * M, 0, -1):

    # 両方みつけた
    if aidx < N and bidx < M and n == A[aidx] and n == B[bidx] and A[aidx] == B[bidx]:
        aidx += 1
        bidx += 1

    # Bの方だけ見つけた
    elif bidx < M and n == B[bidx]:
        ret *= aidx
        bidx += 1

    # Aの方だけ見つけた
    elif aidx < N and n == A[aidx]:
        ret *= bidx
        aidx += 1

    # 両方なかった
    else:
        ret *= (aidx * bidx - (N * M - n))
    ret = ret % MOD

print(ret)
# Original solution
from bisect import bisect
n, m = [int(i) for i in input().split()]
a = [int(i) for i in input().split()]
b = [int(i) for i in input().split()]
a.sort()
b.sort()
ia = 0
ib = 0
cnt = 1
for i in range(1,n*m+1)[::-1]:
    if i in a:
        if i in b:
            cnt *= 1
            ia += 1
            ib += 1
        else:
            cnt *= ib
            cnt %= 1000000007
            ia += 1
    else:
        if i in b:
            cnt *= ia
            cnt %= 1000000007
            ib += 1
        else:
            cnt *= ia*ib - (n*m - i)
            cnt %= 1000000007
if len(a) != len(set(a)) or len(b) != len(set(b)) :
    cnt = 0
print(cnt)


# Optimized solution
from bisect import bisect
n, m = [int(i) for i in input().split()]
a = [int(i) for i in input().split()]
b = [int(i) for i in input().split()]
a.append(0)
b.append(0)
a.sort()
b.sort()
ia = 0
ib = 0
cnt = 1
for i in range(1,n*m+1)[::-1]:
    if i == a[-1]:
        if i == b[-1]:
            cnt *= 1
            a.pop(-1)
            b.pop(-1)
            ia += 1
            ib += 1
        else:
            cnt *= ib
            a.pop(-1)
            cnt %= 1000000007
            ia += 1
    else:
        if i == b[-1]:
            cnt *= ia
            b.pop(-1)
            cnt %= 1000000007
            ib += 1
        else:
            cnt *= ia*ib - (n*m - i)
            cnt %= 1000000007

print(cnt)
# Original solution
from collections import Counter

def solve():
    N, M = list(map(int, input().split()))
    *A, = list(map(int, input().split()))
    *B, = list(map(int, input().split()))
    c = Counter()
    MOD = 10**9+7

    used = set()

    for i in range(N):
        for j in range(M):
            if A[i]==B[j]:
                if A[i] in used:
                    print((0))
                    return
                else:
                    used.add(A[i])
            c[min(A[i], B[j])] += 1

    cd = 0
    ans = 1
    bef = 0
    for i, j in sorted(c.items()):
        cd += (i - bef)
        if i in used:
            # print(cd, j)
            cd -= 1
            for k in range(j-1):
                ans *= (cd-k)
                ans %= MOD
            cd -= j-1
        else:
            # print(cd, j)
            ans *= j
            cd -= 1
            for k in range(j-1):
                ans *= (cd-k)
                ans %= MOD
            cd -= j-1
        bef = i
    print((ans%MOD))

solve()

# Optimized solution
from collections import Counter
import sys
input=sys.stdin.readline


def solve():
    N, M = list(map(int, input().split()))
    *A, = list(map(int, input().split()))
    *B, = list(map(int, input().split()))
    c = Counter()
    MOD = 10**9+7
    used = set()

    for i in range(N):
        for j in range(M):
            if A[i]==B[j]:
                if A[i] in used:
                    print((0))
                    return
                else:
                    used.add(A[i])
            c[min(A[i], B[j])] += 1

    cd = 0
    ans = 1
    bef = 0
    for i, j in sorted(c.items()):
        cd += (i - bef)
        if i not in used:
            ans *= j
        cd -= 1
        for k in range(j-1):
            ans *= (cd-k)
            ans %= MOD
        cd -= j-1
        bef = i
    print((ans%MOD))


if __name__ == "__main__":
    solve()
# Original solution
from collections import Counter
import sys
input=sys.stdin.readline


def solve():
    N, M = list(map(int, input().split()))
    *A, = list(map(int, input().split()))
    *B, = list(map(int, input().split()))
    c = Counter()
    MOD = 10**9+7
    used = set()

    for i in range(N):
        for j in range(M):
            if A[i]==B[j]:
                if A[i] in used:
                    print((0))
                    return
                else:
                    used.add(A[i])
            c[min(A[i], B[j])] += 1

    cd = 0
    ans = 1
    bef = 0
    for i, j in sorted(c.items()):
        cd += (i - bef)
        if i not in used:
            ans *= j
        cd -= 1
        for k in range(j-1):
            ans *= (cd-k)
            ans %= MOD
        cd -= j-1
        bef = i
    print((ans%MOD))


if __name__ == "__main__":
    solve()


# Optimized solution
from collections import Counter
import sys
input=sys.stdin.readline


def solve():
    N, M = list(map(int, input().split()))
    *A, = list(map(int, input().split()))
    *B, = list(map(int, input().split()))
    c = Counter()
    MOD = 10**9+7
    used = set()

    for i in A:
        for j in B:
            if i==j:
                if i in used:
                    print((0))
                    return
                else:
                    used.add(i)
            c[min(i, j)] += 1

    v, ans, bef = 0, 1, 0
    for i, j in sorted(c.items()):
        ans *= 1 if i in used else j
        v += i-bef-1
        for k in range(j-1):
            ans *= v-k
            ans %= MOD
        v -= j-1
        bef = i
    print(ans)


if __name__ == "__main__":
    solve()
# Original solution
# coding:utf-8

import sys
import bisect

# from collections import Counter, defaultdict

INF = float('inf')
MOD = 10 ** 9 + 7


def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def I(): return int(sys.stdin.readline())
def S(): return eval(input())


N, M = LI()
A = LI()
B = LI()

A.sort()
B.sort()

SA = set(A)
SB = set(B)


if N != len(SA) or M != len(SB):
    print((0))
    exit()

ans = 1
num = 0
aa = N
bb = M
for i in range(1, N * M + 1)[::-1]:
    if i in SA and i in SB:
        pass
    elif i in SB:
        while aa != 0 and 0 < i <= A[aa - 1]:
            aa -= 1
        ans *= N - aa
        ans %= MOD
    elif i in SA:
        while bb != 0 and 0 < i <= B[bb - 1]:
            bb -= 1
        ans *= M - bb
        ans %= MOD
    else:
        while aa != 0 and 0 < i <= A[aa - 1]:
            aa -= 1
        while bb != 0 and 0 < i <= B[bb - 1]:
            bb -= 1
        ans *= (M - bb) * (N - aa) - num
        ans %= MOD
    num += 1
    # print(i, ans, num)

print(ans)


# Optimized solution
# coding:utf-8

import sys
INF = float('inf')
MOD = 10 ** 9 + 7

def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x) - 1 for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def II(): return int(sys.stdin.readline())
def SI(): return eval(input())


def main():
    h, w = LI()
    A = LI()
    A.sort()
    B = LI()
    B.sort()

    # A, B内では同じ値は存在できない
    if len(A) != len(set(A)) or len(B) != len(set(B)):
        return 0

    a_i, b_i = h - 1, w - 1
    if h * w > A[a_i] or h * w > B[b_i]:
        return 0

    res = 1
    for n in range(1, h * w + 1)[::-1]:
        while a_i > 0 and A[a_i - 1] >= n:
            a_i -= 1
        while b_i > 0 and B[b_i - 1] >= n:
            b_i -= 1

        if n == A[a_i] and n == B[b_i]:
            res *= 1
        elif n == A[a_i]:
            res *= w - b_i
        elif n == B[b_i]:
            res *= h - a_i
        else:
            res *= (h - a_i) * (w - b_i) - (h * w - n)

        res %= MOD

    return res


print((main()))
# Original solution
import bisect
N,M = list(map(int,input().split()))
A = sorted(list(map(int,input().split())))
B = sorted(list(map(int,input().split())))
sa = set(A)
sb = set(B)
MOD = 10**9+7

if len(sa) != N or len(sb) != M:
    print((0))
    exit()

ans = 1
for n in range(N*M, 0, -1):
    if n in sa and n in sb: continue
    if n in sa:
        vacant = M - bisect.bisect(B,n)
    elif n in sb:
        vacant = N - bisect.bisect(A,n)
    else:
        i = N - bisect.bisect(A,n)
        j = M - bisect.bisect(B,n)
        vacant = i*j - (N*M-n)
        if vacant <= 0:
            print((0))
            exit()
    ans *= vacant
    ans %= MOD

print(ans)

# Optimized solution
N,M = list(map(int,input().split()))
A = list(map(int,input().split()))
B = list(map(int,input().split()))
A.sort()
B.sort()
sa = set(A)
sb = set(B)
if len(sa)!=N or len(sb)!=M:
    print((0))
    exit()
MOD = 10**9+7

ans = 1
w = h = 0
for v in range(N*M,0,-1):
    if v in sa and v in sb:
        w += 1
        h += 1
    elif v in sa:
        ans *= w
        ans %= MOD
        h += 1
    elif v in sb:
        ans *= h
        ans %= MOD
        w += 1
    else:
        free = w*h - (N*M - v)
        if free <= 0:
            print((0))
            exit()
        ans *= free
        ans %= MOD
print(ans)