#include "vector"
#include "set"
#include "map"
#include "unordered_set"
#include "unordered_map"
#include "string"
#include "iostream"
#include "algorithm"
#include "queue"

using namespace std;

#define ll long long
#define INF 2e9
#define INF2 4611686018427387904
//#define MOD 1000000007
#define MOD 998244353
#define MAX_SIZE 1000000000

typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

template<typename T>
ostream& operator<<(ostream& os, const vector<T>& v) { bool first = true; for (const auto& j: v) { if (!first) { os << " "; } first = false; os <<j; } os << "\n"; return os; }
template<typename T>
istream& operator>>(istream& is, vector<T>& v) { for (auto& elem : v) { is >> elem; } return is; }

vector<ll> f;
void set_f(int n) { f.resize(n+1); f[0] = 1; for (int i=1; i<= n; i++) { f[i] = (f[i-1] * i) % MOD;} }
ll gcd(ll a, ll b) { if (b == 0) { return a; } else { return gcd(b, a % b); } }
ll pw(ll x, ll n, ll m=MOD) { if (n == 0) { return 1;} if (n%2 == 0) { return pw((x*x) % m, n/2, m); } return (pw(x, n-1, m) * x) % m; }
ll dv(ll a, ll b) { return (a * pw(b, MOD - 2)) % MOD; }
ll c_n_k(int n, int k) { if (k > n) { return 0; } if (k < 0) { return 0; } return dv(dv(f[n], f[k]), f[n-k]); }

ll phi (ll n) {
    ll result = n;
    for (ll i=2; i*i<=n; ++i) {
        if (n % i == 0) {
            while (n % i == 0) {
                n /= i;
            }
            result -= result / i;
        }
    }
    if (n > 1) {
        result -= result / n;
    }
    return result;
}

class segment_tree_max {
private:
    vector<ll> m;
    vector<ll> delta;
    int n;
    bool is_bulk;

    ll get_val(int i) {
        if (!is_bulk) {
            return m[i];
        }

        ll ans = m[i] + delta[i];
        i /= 2;
        while (i >= 1) {
            ans += delta[i];
            i /= 2;
        }
        return ans;
    }

    void inc(int i, ll val) {
        delta[i] += val;
        i /= 2;
        while (i >= 1) {
            m[i] = max(m[2 * i] + delta[2 * i], m[2 * i + 1] + delta[2 * i + 1]);
            i /= 2;
        }
    }
public:
    segment_tree_max() {
    }
    segment_tree_max(int nn, int def, bool bulk=false) {
        is_bulk = bulk;

        n = 1;
        while (n < nn) {
            n *= 2;
        }

        m.assign(2 * n, def);
        if (is_bulk) {
            delta.assign(2 * n, 0);
        }
    }

    ll get_max(int l, int r) {
        if (l > r) {
            swap(l, r);
        }
        l += n; r += n;

        ll ans = -INF;
        while (l <= r) {
            if (l % 2 == 1) {
                ans = max(ans, get_val(l));
                l++;
            }
            if (r % 2 == 0) {
                ans = max(ans, get_val(r));
                r--;
            }

            l /= 2; r /= 2;
        }

        return ans;
    }

    void inc_bulk(int l, int r, ll val) {
        if (!is_bulk) {
            cout << "cant inc_bulk in not bulk mode" << endl;
            exit(1);
        }

        if (l > r) {
            swap(l, r);
        }
        l += n;
        r += n;

        while (l <= r) {
            if (l % 2 == 1) {
                inc(l, val);
                l++;
            }
            if (r % 2 == 0) {
                inc(r, val);
                r--;
            }

            l /= 2; r /= 2;
        }
    }

    void update(int i, ll val) {
        i += n;
        m[i] = val;
        i /= 2;
        while (i >= 1) {
            if (is_bulk) {
                m[i] = max(m[2 * i] + delta[2 * i], m[2 * i + 1] + delta[2 * i + 1]);
            } else {
                m[i] = max(m[2 * i], m[2 * i + 1]);
            }
            i /= 2;
        }
    }
};

class segment_tree_min {
private:
    segment_tree_max max_tree;
public:
    segment_tree_min() {
    }
    segment_tree_min(int nn, int def=INF, bool bulk=false) {
        max_tree = segment_tree_max(nn, -def, bulk);
    }

    ll get_min(int l, int r) {
        return -max_tree.get_max(l, r);
    }

    void inc_bulk(int l, int r, ll val) {
        max_tree.inc_bulk(l, r, -val);
    }

    void update(int i, ll val) {
        max_tree.update(i, -val);
    }
};

void solve() {
    int n, m, k;
    cin >> n >> m >> k;

    set_f(n);

    ll ans = 0;

    for (int i=0; i <= k; i++) {
        ll x = (c_n_k(n-1, i) * m) % MOD;
        x = (x * pw(m-1, n-i-1)) % MOD;
        ans = (ans + x) % MOD;
    }

    cout << ans;
}


int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);

    if (0) {
        int tests;
        cin >> tests;
        for (int t = 1; t <= tests; t++) {
            //cout << "Case #" << t << ": ";
            solve();
            cout << "\n";
        }
    } else {
        solve();
        cout << endl;
    }

    return 0;
}

Measured memory_bytes: 4716