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: Wrong Answer)

using System;
using static System.Console;

namespace abc167
{
    class Program
    {
        const int keyNum = 998244353;
        static void Main()
        {
            var nmk = ReadLine().Split(' ');
            var n = int.Parse(nmk[0]);
            var m = int.Parse(nmk[1]);
            var k = int.Parse(nmk[2]);

            int[] facts = null;
            int[] revFacts = null;
            GetFactorialsDiv(n, keyNum, out facts, out revFacts);

            var total = 0L;
            for (var i = 0; i <= k; ++i)
            {
                var subTotal = ((long)NCRDiv(n - 1, i, facts, revFacts, keyNum) * m) % keyNum;
                subTotal = (subTotal * Exp(m - 1, n - i - 1, keyNum));
                total = (total + subTotal) % keyNum;
            }
            WriteLine(total);
        }

        static void GetFactorialsDiv(int n, int keyNum, out int[] facts, out int[] revFacts)
        {
            facts = new int[n + 1];
            revFacts = new int[n + 1];

            facts[0] = 1;
            var tmp = 1L;
            for (var i = 1; i <= n; ++i)
            {
                tmp = (tmp * i) % keyNum;
                facts[i] = (int)tmp;
            }
            // n!^-1 = n!^(m-2) (mod m)
            tmp = Exp(facts[n], keyNum - 2, keyNum);
            revFacts[n] = (int)tmp;
            for (var i = n; i > 1; --i)
            {
                tmp = (tmp * i) % keyNum;
                revFacts[i - 1] = (int)tmp;
            }
        }
        static long Exp(int n, int k, int keyNum)
        {
            if (k == 0)
            {
                return 1;
            }
            if (k == 1)
            {
                return n;
            }
            var half = Exp(n, k / 2, keyNum);
            var result = (half * half) % keyNum;
            return ((k % 2) == 0) ? result : ((result * n) % keyNum);
        }
        static int NCRDiv(int n, int r, int[] facts, int[] revFacts, int keyNum)
        {
            if (r == 0)
            {
                return 1;
            }
            if (r == 1)
            {
                return n;
            }
            var result = 1L;
            result = (result * facts[n]) % keyNum;
            result = (result * revFacts[r]) % keyNum;
            result = (result * revFacts[n - r]) % keyNum;
            return (int)result;
        }
    }
}