Problem:
Score : 500 points

Problem Statement

There are N blocks arranged in a row. Let us paint these blocks.

We will consider two ways to paint the blocks different if and only if there is a block painted in different colors in those two ways.

Find the number of ways to paint the blocks under the following conditions:

For each block, use one of the M colors, Color 1 through Color M, to paint it. It is not mandatory to use all the colors.

There may be at most K pairs of adjacent blocks that are painted in the same color.

Since the count may be enormous, print it modulo 998244353.

Constraints

All values in input are integers.

1 \leq N, M \leq 2 \times 10^5

0 \leq K \leq N - 1

Input

Input is given from Standard Input in the following format:

N M K

Output

Print the answer.

Sample Input 1

3 2 1

Sample Output 1

6

The following ways to paint the blocks satisfy the conditions: 112, 121, 122, 211, 212, and 221. Here, digits represent the colors of the blocks.

Sample Input 2

100 100 0

Sample Output 2

73074801

Sample Input 3

60522 114575 7559

Sample Output 3

479519525

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

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AtCoder.Contest.E
{
	class Program
	{
		const long MOD = 998244353;

		public static void Main(string[] args)
		{
			var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
			Console.SetOut(sw);

			Scanner cin = new Scanner();

			int n = cin.nextInt();
			int m = cin.nextInt();
			int k = cin.nextInt();

			long ans = 0;
			long now = 1;
			for (int i = 1; i <= k; i++)
			{
				now *= n - i;
				now %= MOD;
				now *= modinv(i, MOD);
				now %= MOD;
			}
			now *= m;
			now %= MOD;
			for (int i = 0; i < n-k-1; i++)
			{
				now *= m - 1;
				now %= MOD;
			}
			ans += now;
			for (int i = 0; i <= k; i++)
			{
				now *= k - i;
				now %= MOD;
				now *= modinv(n - k + i, MOD);
				now %= MOD;
				now *= m - 1;
				now %= MOD;

				ans += now;
				ans %= MOD;
			}

			Console.WriteLine(ans);

			Console.Out.Flush();
		}

		static long modinv(long a, long m)
		{
			long b = m, u = 1, v = 0;
			while (b>0)
			{
				long t = a / b;
				a -= t * b; swap(ref a, ref b);
				u -= t * v; swap(ref u, ref v);
			}
			u %= m;
			if (u < 0) u += m;
			return u;
		}

		static void swap<T>(ref T a,ref T b)
		{
			var t = a;
			a = b;
			b = t;

		}
	}

	class Scanner
	{
		string[] s;
		int i;

		char[] cs = new char[] { ' ' };

		public Scanner()
		{
			s = new string[0];
			i = 0;
		}

		public string next()
		{
			if (i < s.Length) return s[i++];
			string st = Console.ReadLine();
			while (st == "") st = Console.ReadLine();
			s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
			if (s.Length == 0) return next();
			i = 0;
			return s[i++];
		}

		public int nextInt()
		{
			return int.Parse(next());
		}

		public int[] ArrayInt(int N, int add = 0)
		{
			int[] Array = new int[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = nextInt() + add;
			}
			return Array;
		}

		public long nextLong()
		{
			return long.Parse(next());
		}

		public long[] ArrayLong(int N, long add = 0)
		{
			long[] Array = new long[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = nextLong() + add;
			}
			return Array;
		}

		public double nextDouble()
		{
			return double.Parse(next());
		}

		public double[] ArrayDouble(int N, double add = 0)
		{
			double[] Array = new double[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = nextDouble() + add;
			}
			return Array;
		}
	}
}