#pragma GCC optimize("O3")
#pragma GCC target("sse4")

#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <typeinfo>

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef pair<ld, ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T>
using Tree =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define rep(i, a, b) for (int i = a; i < b; i++)
#define rrep(i, a, b) for (int i = a; i >= b; i--)
#define FOR(i, a, b) for (int i = a; i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i, a, b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i, a) for (int i = (a)-1; i >= 0; i--)

#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()
#define shandom_ruffle random_shuffle

const int MOD = 1000000007;
const ll INF = 1e18;
const int MX = 100001;  // check the limits, dummy

typedef long long ll;
const int inf = INT_MAX / 2;
const ll infl = 1LL << 60;
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

template <class T>
void print(const vector<T> v) {
  cout << "[ ";
  F0R(i, v.size()) { cout << v[i] << ' '; }
  cout << "]" << '\n';
}

int mod(int i, int j) {
  return (i % j) < 0 ? (i % j) + 0 + (j < 0 ? -j : j) : (i % j + 0);
}

unsigned euclidean_gcd(unsigned a, unsigned b) {
  if (a < b) return euclidean_gcd(b, a);
  unsigned r;
  while ((r = a % b)) {
    a = b;
    b = r;
  }
  return b;
}

int middleOfThree(int a, int b, int c) {
  // Checking for b
  if ((a < b && b < c) || (c < b && b < a)) return b;

  // Checking for a
  else if ((b < a && a < c) || (c < a && a < b))
    return a;

  else
    return c;
}

int vector_finder(std::vector<int> vec, int number) {
  auto itr = std::find(vec.begin(), vec.end(), number);
  size_t index = std::distance(vec.begin(), itr);
  if (index != vec.size()) {  // 発見できたとき
    return 1;
  } else {  // 発見できなかったとき
    return 0;
  }
}

template <typename T>
std::string printVector(const std::vector<T> &data) {
  std::stringstream ss;
  std::ostream_iterator<T> out_it(ss, ", ");
  ss << "[";
  std::copy(data.begin(), data.end() - 1, out_it);
  ss << data.back() << "]";
  return ss.str();
}

ll mpow(ll x, ll n, ll M) {
  // x^n(mod M) ←普通にpow(x,n)では溢れてしまうため，随時mod計算
  ll ans = 1;
  while (n != 0) {
    if (n & 1) ans = ans * x % M;
    x = x * x % M;
    n = n >> 1;
  }
  return ans;
}

vector<ll> fac(300001);   // n!(mod M)
vector<ll> ifac(300001);  // k!^{M-2} (mod M)

ll comb(ll a, ll b, ll M) {  // aCbをmod計算
  if (a == 0 && b == 0) return 1;
  if (a < b || a < 0) return 0;
  ll tmp = ifac[a - b] * ifac[b] % M;
  return tmp * fac[a] % M;
}

// --------------------------------------------------------
// This is tool
// --------------------------------------------------------

// string S;
// ll cnt[2020];

void Main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);

  ll N, M, K;
  ll mod = 998244353;
  cin >> N >> M >> K;

  //大した量ではないので，先にfax[i]とifax[i]を全て計算しておく
  fac[0] = 1;
  ifac[0] = 1;
  for (ll i = 0; i < 300000; i++) {
    fac[i + 1] = fac[i] * (i + 1) % mod;  // n!(mod M)
    ifac[i + 1] = ifac[i] * mpow(i + 1, mod - 2, mod) %
                  mod;  // k!^{M-2} (mod M) ←累乗にmpowを採用
  }

  ll ans = 0;
  for (ll i = 0; i < K + 1; i++) {
    ans += M * comb(N - 1, i, mod) % mod * mpow(M - 1, N - 1 - i, mod) % mod;
    ans %= mod;
  }
  cout << ans << endl;
}

int main() {
  std::cin.tie(nullptr);
  std::ios_base::sync_with_stdio(false);
  std::cout << std::fixed << std::setprecision(15);
  Main();
}

Measured memory_bytes: 7840