Buggy python submission (verdict: Time Limit Exceeded):
from scipy.special import perm, comb

mod = 10 ** 9 + 7
N, M = map(int, input().split())

A = perm(M, N, exact=True) % mod

B = 0
for i in range(N + 1):
    B += (-1) ** i * comb(N, i, exact=True) * perm(M - i, N - i, exact=True) % mod

print(A * B % mod)

Fixed submission:
mod = 10 ** 9 + 7
N, M = map(int, input().split())

class Combination:
    def __init__(self, size):
        self.size = size + 2
        self.fact = [1, 1] + [0] * size
        self.factInv = [1, 1] + [0] * size
        self.inv = [0, 1] + [0] * size

        for i in range(2, self.size):
            self.fact[i] = self.fact[i - 1] * i % mod
            self.inv[i] = -self.inv[mod % i] * (mod // i) % mod
            self.factInv[i] = self.factInv[i - 1] * self.inv[i] % mod

    def npr(self, n, r):
        if n < r or n < 0 or r < 0:
            return 0
        return self.fact[n] * self.factInv[n - r] % mod

    def ncr(self, n, r):
        if n < r or n < 0 or r < 0:
            return 0
        return self.fact[n] * (self.factInv[r] * self.factInv[n - r] % mod) % mod

    def nhr(self, n, r):  # 重複組合せ: x_1 + ... + x_n = r
        return self.ncr(n + r - 1, n - 1)

comb = Combination(M + 100)

A = comb.npr(M, N) % mod

B = 0
for i in range(N + 1):
    B += (-1) ** i * comb.ncr(N, i) * comb.npr(M - i, N - i) % mod

print(A * B % mod)

Buggy python submission (verdict: Time Limit Exceeded):
from scipy.special import perm, comb

mod = 10 ** 9 + 7
N, M = map(int, input().split())

def cmb(n, r):
    if n - r < r: r = n - r
    if r == 0: return 1
    if r == 1: return n

    numerator = [n - r + k + 1 for k in range(r)]
    denominator = [k + 1 for k in range(r)]

    for p in range(2,r+1):
        pivot = denominator[p - 1]
        if pivot > 1:
            offset = (n - r) % p
            for k in range(p-1,r,p):
                numerator[k - offset] /= pivot
                denominator[k] /= pivot

    result = 1
    for k in range(r):
        if numerator[k] > 1:
            result *= int(numerator[k])

    return result

A = perm(M, N, exact=True)

B = 0
for i in range(N + 1):
    B += (-1) ** i * cmb(N, i) * perm(M - i, N - i, exact=True)

print(A * B % mod)

Fixed submission:
mod = 10 ** 9 + 7
N, M = map(int, input().split())

class Combination:
    def __init__(self, size):
        self.size = size + 2
        self.fact = [1, 1] + [0] * size
        self.factInv = [1, 1] + [0] * size
        self.inv = [0, 1] + [0] * size

        for i in range(2, self.size):
            self.fact[i] = self.fact[i - 1] * i % mod
            self.inv[i] = -self.inv[mod % i] * (mod // i) % mod
            self.factInv[i] = self.factInv[i - 1] * self.inv[i] % mod

    def npr(self, n, r):
        if n < r or n < 0 or r < 0:
            return 0
        return self.fact[n] * self.factInv[n - r] % mod

    def ncr(self, n, r):
        if n < r or n < 0 or r < 0:
            return 0
        return self.fact[n] * (self.factInv[r] * self.factInv[n - r] % mod) % mod

    def nhr(self, n, r):  # 重複組合せ: x_1 + ... + x_n = r
        return self.ncr(n + r - 1, n - 1)

comb = Combination(M + 100)

A = comb.npr(M, N) % mod

B = 0
for i in range(N + 1):
    B += (-1) ** i * comb.ncr(N, i) * comb.npr(M - i, N - i) % mod

print(A * B % mod)

Buggy python submission (verdict: Runtime Error):
from scipy.special import perm, comb

mod = 10 ** 9 + 7
N, M = map(int, input().split())

A = perm(M, N, exact=True) % mod

B = 0
for i in range(N + 1):
    B += (-1) ** i * comb(N, i, exact=True) * perm(M - i, N - i, exact=True) % mod

print(A * B)

Fixed submission:
mod = 10 ** 9 + 7
N, M = map(int, input().split())

class Combination:
    def __init__(self, size):
        self.size = size + 2
        self.fact = [1, 1] + [0] * size
        self.factInv = [1, 1] + [0] * size
        self.inv = [0, 1] + [0] * size

        for i in range(2, self.size):
            self.fact[i] = self.fact[i - 1] * i % mod
            self.inv[i] = -self.inv[mod % i] * (mod // i) % mod
            self.factInv[i] = self.factInv[i - 1] * self.inv[i] % mod

    def npr(self, n, r):
        if n < r or n < 0 or r < 0:
            return 0
        return self.fact[n] * self.factInv[n - r] % mod

    def ncr(self, n, r):
        if n < r or n < 0 or r < 0:
            return 0
        return self.fact[n] * (self.factInv[r] * self.factInv[n - r] % mod) % mod

    def nhr(self, n, r):  # 重複組合せ: x_1 + ... + x_n = r
        return self.ncr(n + r - 1, n - 1)

comb = Combination(M + 100)

A = comb.npr(M, N) % mod

B = 0
for i in range(N + 1):
    B += (-1) ** i * comb.ncr(N, i) * comb.npr(M - i, N - i) % mod

print(A * B % mod)