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.Linq;

namespace AtCoder.R167.E
{
    public static class Solver
    {
        public static void Main()
        {
            using (var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false })
            {
                Solve(Console.In, sw);
            }
        }

        public static void Solve(TextReader tr, TextWriter tw)
        {
            WriteAnswer(tw, Parse(tr));
        }

        private static void WriteAnswer(TextWriter tw, int answer)
        {
            tw.WriteLine(answer);
        }

        private static int Parse(TextReader tr)
        {
            var w = tr.ReadLine().Split().Select(c => long.Parse(c)).ToArray();
            
            return Calc(w[0], w[1], w[2]);
        }

        public static int Calc(long n, long m, long k)
        {
            var modulo = new Modulo(998244353);

            var res = modulo.Create(0);

            var combination = new ModuloInteger[k + 1];
            combination[0] = modulo.Create(1);

            for (int i = 1; i <= k; ++i)
            {
                combination[i] = combination[i - 1] * (n - i) / i;
            }

            for (int i = 0; i <= k; ++i)
            {
                res += combination[i] * m * modulo.Pow(m - 1, n - 1 - i);
            }
            return res;
        }
    }

    public struct ModuloInteger : IEquatable<ModuloInteger>
    {
        readonly long value;
        readonly int mod;

        internal ModuloInteger(long value, int mod)
        {
            this.value = (value + mod) % mod;
            this.mod = mod;
        }

        public bool Equals(ModuloInteger other)
        {
            return mod == other.mod && value == other.value;
        }

        public static ModuloInteger Pow(ModuloInteger x, long n)
        {
            var res = new ModuloInteger(1, x.mod);

            for (; n > 0; n >>= 1, x *= x)
                if ((n & 1) == 1)
                    res *= x;

            return res;
        }

        public override bool Equals(object obj)
        {
            return obj is ModuloInteger && Equals((ModuloInteger)obj);
        }

        public override int GetHashCode()
        {
            return value.GetHashCode() ^ mod.GetHashCode();
        }

        public static bool operator ==(ModuloInteger left, ModuloInteger right)
        {
            return left.Equals(right);
        }

        public static bool operator !=(ModuloInteger left, ModuloInteger right)
        {
            return !(left == right);
        }

        public static ModuloInteger LeftShift(ModuloInteger left, int right)
        {
            return left * Pow(new ModuloInteger(2, left.mod), right);
        }

        public static ModuloInteger operator <<(ModuloInteger left, int right)
        {
            return LeftShift(left, right);
        }

        public static ModuloInteger Add(ModuloInteger left, long right)
        {
            return new ModuloInteger(left.value + right, left.mod);
        }

        public static ModuloInteger operator +(ModuloInteger left, long right)
        {
            return Add(left, right);
        }

        public static ModuloInteger operator -(ModuloInteger left, long right)
        {
            return new ModuloInteger(left.value - right, left.mod);
        }

        public static ModuloInteger operator -(long left, ModuloInteger right)
        {
            return new ModuloInteger(left - right.value, right.mod);
        }

        public static ModuloInteger operator ++(ModuloInteger m)
        {
            return Increment(m);
        }
        public static ModuloInteger Increment(ModuloInteger item)
        {
            return item + 1;
        }

        public static ModuloInteger Multiply(ModuloInteger left, long right)
        {
            return new ModuloInteger(left.value * right, left.mod);
        }

        public static ModuloInteger operator *(ModuloInteger left, long right)
        {
            return Multiply(left, right);
        }

        public static ModuloInteger operator /(ModuloInteger left, long right)
        {
            return Pow(new ModuloInteger(right, left.mod), left.mod - 2) * left;
        }

        public static implicit operator int(ModuloInteger value)
        {
            return ToInt32(value);
        }

        public static int ToInt32(ModuloInteger value)
        {
            return (int)value.value;
        }
    }

    public class Modulo
    {
        readonly int mod;
        public Modulo(int mod)
        {
            this.mod = mod;
        }

        public ModuloInteger Create(long v)
        {
            return new ModuloInteger(v, mod);
        }

        public ModuloInteger Pow(long value, long exponent)
        {
            return ModuloInteger.Pow(Create(value), exponent);
        }
    }
}