#include <bits/stdc++.h>
using namespace std;

struct init_ { init_(){ cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(10); } } init_;

template<class C> using iodef_rng_t = typename enable_if<decltype(declval<C>().begin(), true_type{})::value && !is_same<C, string>::value>::type;
template<class C, class = iodef_rng_t<C>> istream& operator>>(istream& in, C& c) { for (auto& v : c) { in >> v; } return in; }
template<class C, class = iodef_rng_t<C>> ostream& operator<<(ostream& out, const C& c) { int i = 0; for (const auto& v : c) { if (i++) { out << ' '; } out << v; } return out; }
template<size_t N, class T, class R> using when_last = typename enable_if<N == tuple_size<remove_reference_t<T>>::value - 1, R>::type;
template<size_t N, class T, class R> using when_init = typename enable_if<N != tuple_size<remove_reference_t<T>>::value - 1, R>::type;
template<size_t N = 0, class T> auto operator>>(istream& in, T&& t) -> when_last<N, T, istream&> { return in >> get<N>(t); }
template<size_t N = 0, class T> auto operator>>(istream& in, T&& t) -> when_init<N, T, istream&> { return operator>><N + 1>(in >> get<N>(t), forward<T>(t)); }
template<size_t N = 0, class T> auto operator<<(ostream& out, const T& t) -> when_last<N, T, ostream&> { return out << get<N>(t); }
template<size_t N = 0, class T> auto operator<<(ostream& out, const T& t) -> when_init<N, T, ostream&> { return operator<<<N + 1>(out << get<N>(t) << ' ', t); }

#ifdef LOCAL
template<class T> void trace_(const char* s, const T& v) { cerr << s << "=" << v; }
template<class T, class... Ts> void trace_(const char* s, const T& v, const Ts&... vs) { for (; *s != ','; ++s) { cerr << *s; } cerr << "=" << v << ","; trace_(++s, vs...); }
#define TRACE(...) (cerr << "\033[2m\033[33m", trace_(#__VA_ARGS__, __VA_ARGS__), cerr << "\033[0m\n")
#else
#define TRACE(...)
#endif

template<u_int32_t Mod = 998244353> class Modint {
    int64_t val;
public:
    static constexpr u_int32_t mod = Mod;
    Modint(int64_t v = 0) noexcept : val(v % mod) { if (val < 0) val += mod; }
    int64_t value() const noexcept { return val; }
    friend istream& operator>>(istream &is, Modint<mod>& x) { int64_t v; is >> v; x = v; return is; }
    friend ostream& operator<<(ostream &os, const Modint<mod>& x) { return os << x.val; }
    bool operator==(const Modint<mod>& r) const noexcept { return val == r.val; }
    bool operator!=(const Modint<mod>& r) const noexcept { return val != r.val; }
    Modint<mod> operator-() const noexcept { return val ? mod - val : 0; }
    Modint<mod> operator+(const Modint<mod>& r) const noexcept { return Modint(*this) += r; }
    Modint<mod> operator-(const Modint<mod>& r) const noexcept { return Modint(*this) -= r; }
    Modint<mod> operator*(const Modint<mod>& r) const noexcept { return Modint(*this) *= r; }
    Modint<mod> operator/(const Modint<mod>& r) const noexcept { return Modint(*this) /= r; }
    Modint<mod>& operator+=(const Modint<mod>& r) noexcept { val += r.val; if (val >= mod) val -= mod; return *this; }
    Modint<mod>& operator-=(const Modint<mod>& r) noexcept { val -= r.val; if (val < 0) val += mod; return *this; }
    Modint<mod>& operator*=(const Modint<mod>& r) noexcept { val = val * r.val % mod; return *this; }
    Modint<mod>& operator/=(const Modint<mod>& r) noexcept {
        int64_t a = r.val, b = mod, u = 1, v = 0, t = 0;
        while (b) { t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v); }
        val = val * u % mod;
        if (val < 0) val += mod;
        return *this;
    }
    Modint<mod> pow(u_int32_t n) const noexcept {
        Modint<mod> r = 1, t = *this;
        for (;n > 0;  n >>= 1) { if (n & 1) { r *= t; } t *= t; }
        return r;
    }
};

template<u_int32_t Mod = 998244353> class Modop {
    vector<int64_t> fs, fis;
public:
    static constexpr u_int32_t mod = Mod;
    Modop(u_int32_t max) noexcept : fs(max + 1), fis(max + 1) {
        fs[0] = fs[1] = fis[0] = fis[1] = 1;
        for (u_int32_t i = 2; i <= max; i++) fs[i] = fs[i - 1] * i % mod;
        fis[max] = (Modint<mod>(1) / fs[max]).value();
        for (u_int32_t i = max; i > 2; i--) fis[i - 1] = fis[i] * i % mod;
    }
    int64_t fac(u_int32_t n) const noexcept { return fs[n]; }
    int64_t fac_inv(u_int32_t n) const noexcept { return fis[n]; }
    int64_t comb(u_int32_t n, u_int32_t k) const noexcept { return (n < k) ? 0 : fs[n] * (fis[k] * fis[n - k] % mod) % mod; }
};

int main() {
    int n, m, K;
    cin >> n >> m >> K;
    Modop mop(n);
    Modint ans = 0;
    for (int k = 0; k <= K; k++) {
        ans += Modint(mop.comb(n - 1, k)) * m * Modint(m - 1).pow(n - k - 1);
        TRACE(ans);
    }
    cout << ans << '\n';
}


Measured memory_bytes: 6364