Problem p03152 (python)

Fixed submission:
import sys

def comb(n, r, fact, revfac, mod):
    return (fact[n] * revfac[n-r] * revfac[r]) % mod

def solve():
    input = sys.stdin.readline
    N, M = map(int, input().split())
    A = [int(a) for a in input().split()]
    B = [int(b) for b in input().split()]
    A.sort()
    B.sort()
    if len(A) > len(set(A)) or len(B) > len(set(B)):
        total = 0
    elif A[-1] != N * M or B[-1] != N * M:
        total = 0
    else:
        mod = 7 + 10 ** 9
        factorial = [1] * 1000001
        revfac = [1] * 1000001
        for i in range(1, 1000001):
            factorial[i] = (factorial[i-1] * i) % mod
        revfac[1000000] = pow(factorial[1000000], mod-2, mod)
        for i in reversed(range(1, 1000000)):
            revfac[i] = (revfac[i + 1] * (i + 1)) % mod
    
        total = 1
        row, line = 0, 0
        used = 0
        count = 0
    
        while row < M and line < N:
            #####debag#####
            #print(count, A[line], B[row], used)
            #####debag#####

            if A[line] < B[row]:
                if A[line] - used >= M - row:
                    ##
                    #print(A[line] - used, M - row)
                    ## 
                    total *= (factorial[M - row] * comb(A[line] - used - 1, M - row - 1, factorial, revfac, mod)) % mod
                    total %= mod
                    line += 1
                    used += M - row
                else:
                    total = 0
                    break
            elif A[line] > B[row]:
                if B[row] - used >= N - line:
                    ##
                    #print(B[row] - used, N - line)
                    ##
                    total *= (factorial[N - line] * comb(B[row] - used - 1, N - line - 1, factorial, revfac, mod)) % mod
                    total %= mod
                    row += 1
                    used += N - line
                else: 
                    total = 0
                    break
            else:
                if A[line] - used >= N - line + M - row - 1:
                    ##
                    #print(A[line]-used, N + M - line - row - 1)
                    ##
                    total *= (factorial[N - line + M - row - 2] * comb(A[line] - used - 1, N - line + M - row - 2, factorial, revfac, mod)) % mod
                    total %= mod
                    used += N - line + M - row - 1
                    line += 1
                    row += 1   
                else:
                    total = 0
                    break

            #####debag######
            #count += 1
            #print(total)
            #####debag######

    print(total)

    return

if __name__ == "__main__":
    solve()

Buggy submission (verdict: Runtime Error):
import sys

def comb(n, r, fact, revfac, mod):
    return (fact[n] * revfac[n-r] * revfac[r]) % mod

def solve():
    input = sys.stdin.readline
    N, M = map(int, input().split())
    A = [int(a) for a in input().split()]
    B = [int(b) for b in input().split()]
    A.sort()
    B.sort()
    if len(A) > len(set(A)) or len(B) > len(set(B)):
        total = 0
    elif A[-1] != N * M or B[-1] != N * M:
        total = 0
    else:
        mod = 7 + 10 ** 9
        factorial = [1] * 2001
        revfac = [1] * 2001
        for i in range(1, 2001):
            factorial[i] = (factorial[i-1] * i) % mod
        revfac[2000] = pow(factorial[2000], mod-2, mod)
        for i in reversed(range(1, 2000)):
            revfac[i] = (revfac[i + 1] * (i + 1)) % mod
    
        total = 1
        row, line = 0, 0
        used = 0
        count = 0
    
        while row < M and line < N:
            #####debag#####
            #print(count, A[line], B[row], used)
            #####debag#####

            if A[line] < B[row]:
                if A[line] - used >= M - row:
                    ##
                    #print(A[line] - used, M - row)
                    ## 
                    total *= (factorial[M - row] * comb(A[line] - used - 1, M - row - 1, factorial, revfac, mod)) % mod
                    total %= mod
                    line += 1
                    used += M - row
                else:
                    total = 0
                    break
            elif A[line] > B[row]:
                if B[row] - used >= N - line:
                    ##
                    #print(B[row] - used, N - line)
                    ##
                    total *= (factorial[N - line] * comb(B[row] - used - 1, N - line - 1, factorial, revfac, mod)) % mod
                    total %= mod
                    row += 1
                    used += N - line
                else: 
                    total = 0
                    break
            else:
                if A[line] - used >= N - line + M - row - 1:
                    ##
                    #print(A[line]-used, N + M - line - row - 1)
                    ##
                    total *= (factorial[N - line + M - row - 2] * comb(A[line] - used - 1, N - line + M - row - 2, factorial, revfac, mod)) % mod
                    total %= mod
                    used += N - line + M - row - 1
                    line += 1
                    row += 1   
                else:
                    total = 0
                    break

            #####debag######
            #count += 1
            #print(total)
            #####debag######

    print(total)

    return

if __name__ == "__main__":
    solve()

Buggy submission (verdict: Runtime Error):
import sys

def comb(n, r, fact, revfac, mod):
    return (fact[n] * revfac[n-r] * revfac[r]) % mod

def solve():
    input = sys.stdin.readline
    N, M = map(int, input().split())
    A = [int(a) for a in input().split()]
    B = [int(b) for b in input().split()]
    A.sort()
    B.sort()
    if len(A) > len(set(A)) or len(B) > len(set(B)):
        total = 0
    elif A[-1] != N * M or B[-1] != N * M:
        total = 0
    else:
        mod = 7 + 10 ** 9
        factorial = [1] * 1001
        revfac = [1] * 1001
        for i in range(1, 1001):
            factorial[i] = (factorial[i-1] * i) % mod
        revfac[1000] = pow(factorial[1000], mod-2, mod)
        for i in reversed(range(1, 1000)):
            revfac[i] = (revfac[i + 1] * (i + 1)) % mod
    
        total = 1
        row, line = 0, 0
        used = 0
        count = 0
    
        while row < M and line < N:
            #####debag#####
            #print(count, A[line], B[row], used)
            #####debag#####

            if A[line] < B[row]:
                if A[line] - used >= M - row:
                    ##
                    #print(A[line] - used, M - row)
                    ## 
                    total *= (factorial[M - row] * comb(A[line] - used - 1, M - row - 1, factorial, revfac, mod)) % mod
                    total %= mod
                    line += 1
                    used += M - row
                else:
                    total = 0
                    break
            elif A[line] > B[row]:
                if B[row] - used >= N - line:
                    ##
                    #print(B[row] - used, N - line)
                    ##
                    total *= (factorial[N - line] * comb(B[row] - used - 1, N - line - 1, factorial, revfac, mod)) % mod
                    total %= mod
                    row += 1
                    used += N - line
                else: 
                    total = 0
                    break
            else:
                if A[line] - used >= N - line + M - row - 1:
                    ##
                    #print(A[line]-used, N + M - line - row - 1)
                    ##
                    total *= (factorial[N - line + M - row - 2] * comb(A[line] - used - 1, N - line + M - row - 2, factorial, revfac, mod)) % mod
                    total %= mod
                    used += N - line + M - row - 1
                    line += 1
                    row += 1   
                else:
                    total = 0
                    break

            #####debag######
            #count += 1
            #print(total)
            #####debag######

    print(total)

    return

if __name__ == "__main__":
    solve()