Problem:
Score : 500 points

Problem Statement

Count the pairs of length-N sequences consisting of integers between 1 and M (inclusive), A_1, A_2, \cdots, A_{N} and B_1, B_2, \cdots, B_{N}, that satisfy all of the following conditions:

A_i \neq B_i, for every i such that 1\leq i\leq N.

A_i \neq A_j and B_i \neq B_j, for every (i, j) such that 1\leq i < j\leq N.

Since the count can be enormous, print it modulo (10^9+7).

Constraints

1\leq N \leq M \leq 5\times10^5

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N M

Output

Print the count modulo (10^9+7).

Sample Input 1

2 2

Sample Output 1

2

A_1=1,A_2=2,B_1=2,B_2=1 and A_1=2,A_2=1,B_1=1,B_2=2 satisfy the conditions.

Sample Input 2

2 3

Sample Output 2

18

Sample Input 3

141421 356237

Sample Output 3

881613484

Solution in C# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;

namespace AtCoder0627
{
	class Program
	{
		static void Main(string[] args)
		{
			E();
		}

		const long mod = 1000000007;

		static long xGCD(long a, long b, out long x, out long y)
		{
			if (b == 0)
			{
				x = 1;
				y = 0;
				return a;
			}

			long x1, y1;
			long gcd = xGCD(b, a % b, out x1, out y1);
			x = y1;
			y = x1 - a / b * y1;
			return gcd;
		}
		static long inverse(long a)
		{
			long x, y;
			xGCD(a, (int)mod, out x, out y);
			return x;
		}

		private static void E()
		{
			var ints = Console.ReadLine().Split().Select(x => long.Parse(x)).ToArray();
			var n = ints[0];
			var m = ints[1];

			var factorials = new long[m + 1];
			var inverses = new long[m + 1];
			inverses[0] = 1;
			factorials[0] = 1;
			for (int i = 1; i < factorials.Length; i++)
			{
				factorials[i] = (factorials[i - 1] * i) % mod;
				inverses[i] = inverse(factorials[i]);
			}

			ModVal score = 0;

			for (int i = 0; i <= n; i++)
			{
				ModVal basev = factorials[m - i];
				basev *= inverses[m - n];
				basev *= basev;

				basev *= factorials[n];
				basev *= inverses[i];
				basev *= inverses[n - i];
				basev *= factorials[m];
				basev *= inverses[m - i];
				if (i % 2 == 0)
					score += basev;
				else
					score -= basev;
			}

			long score2 = (score.Val + mod) % mod;

			Console.WriteLine(score2);
		}

		private static void D()
		{
			long n = long.Parse(Console.ReadLine());
			long s = 0;

			for (long i = 1; i <= n; i++)
			{
				var count = n / i;
				s += ((count + 1) * count / 2) * i;
			}

			Console.WriteLine(s);
		}

		private static void C()
		{
			var ints = Console.ReadLine().Split().Select(x => long.Parse(x)).ToArray();
			var n = ints[0];
			var m = ints[1];
			long k = ints[2];

			var a = Console.ReadLine().Split().Select(x => long.Parse(x)).ToArray();
			var b = Console.ReadLine().Split().Select(x => long.Parse(x)).ToArray();
			long max = 0;
			var sa = InclusiveSums(a);
			var sb = InclusiveSums(b);
			long sum = 0;

			for (int i = 0; i <= Math.Max(n, m); i++)
			{
				var maxOnlyA = UpperBound(i, a.Length, t => sa[t] - sa[i] <= k - sum) - i;
				var maxOnlyB = UpperBound(i, b.Length, t => sb[t] - sb[i] <= k - sum) - i;

				max = Math.Max(max, Math.Max(maxOnlyA, maxOnlyB) + 2 * i);
				if (i >= n || i >= m || sum + a[i] + b[i] > k)
					break;

				sum += a[i];
				sum += b[i];
			}

			Console.WriteLine(max);
		}

		public static long[] InclusiveSums(long[] list)
		{
			if (list.Length == 0)
				return Array.Empty<long>();

			var result = new long[list.Length + 1];
			result[0] = 0;
			for (int i = 0; i < result.Length - 1; i++)
				result[i + 1] = result[i] + list[i];

			return result;
		}

		public static long UpperBound(long min, long max, Predicate<long> test)
		{
			long ans = min;
			long s = min;
			long e = max;
			while (s <= e)
			{
				long mid = (s + e) / 2;
				if (test(mid))
				{
					ans = mid;
					s = mid + 1;
				}
				else
					e = mid - 1;
			}

			return ans;
		}

		private static void B()
		{
			var s = Console.ReadLine();
			var t = Console.ReadLine();
			var count = Enumerable.Range(0, s.Length).Count(x => s[x] != t[x]);
			Console.WriteLine(count);
		}

		private static void A()
		{
			var a = int.Parse(Console.ReadLine());
			Console.WriteLine(a + a * a + a * a * a);
		}
	}

	public struct ModVal
	{
		public const long Mod = (long)1e9 + 7;
		public readonly long Val;

		public ModVal(long val)
		{
			Val = val % Mod;
		}

		public override bool Equals(object obj) => obj is ModVal && Val == ((ModVal)obj).Val;
		public override int GetHashCode() => Val.GetHashCode();
		public override string ToString() => Val.ToString();
		public static ModVal operator +(ModVal a, ModVal b) => new ModVal(a.Val + b.Val);
		public static ModVal operator -(ModVal a, ModVal b) => new ModVal(a.Val - b.Val);
		public static ModVal operator *(ModVal a, ModVal b) => new ModVal(a.Val * b.Val);
		public static ModVal operator /(ModVal a, ModVal b) => new ModVal(a.Val / b.Val);
		public static bool operator ==(ModVal a, ModVal b) => a.Val == b.Val;
		public static bool operator !=(ModVal a, ModVal b) => a.Val != b.Val;
		public static implicit operator ModVal(long a) => new ModVal(a);
	}
}