#include <bits/stdc++.h>
using namespace std;
namespace Poly {
const int L = 1 << 20;
const long long P = 998244353LL;
int lim, pos[L];
inline void deb(vector<long long> c) {
  for (int i = 0; i < (int)c.size(); i++)
    printf("%lld%c", c[i], " \n"[i == (int)c.size() - 1]);
}
inline long long fpow(long long x, long long y) {
  long long res = 1;
  for (; y > 0; y >>= 1) {
    if (y & 1) res = res * x % P;
    x = x * x % P;
  }
  return res;
}
const long long inv2 = fpow(2, P - 2);
template <typename T>
inline void inc(T &x, T y) {
  x += y;
  if (x >= P) x -= P;
}
template <typename T>
inline void sub(T &x, T y) {
  x -= y;
  if (x < 0) x += P;
}
inline void prework(int len) {
  int l = 0;
  for (lim = 1; lim < len; lim <<= 1, ++l)
    ;
  for (int i = 0; i < lim; i++)
    pos[i] = (pos[i >> 1] >> 1) | ((i & 1) << (l - 1));
}
inline void ntt(vector<long long> &c, int opt) {
  c.resize(lim, 0);
  for (int i = 0; i < lim; i++)
    if (i < pos[i]) swap(c[i], c[pos[i]]);
  for (int i = 1; i < lim; i <<= 1) {
    long long wn = fpow(3, (P - 1) / (i << 1));
    if (opt == -1) wn = fpow(wn, P - 2);
    for (int len = i << 1, j = 0; j < lim; j += len) {
      long long w = 1;
      for (int k = 0; k < i; k++, w = w * wn % P) {
        long long x = c[j + k], y = w * c[j + k + i] % P;
        c[j + k] = (x + y) % P, c[j + k + i] = (x - y + P) % P;
      }
    }
  }
  if (opt == -1) {
    long long inv = fpow(lim, P - 2);
    for (int i = 0; i < lim; i++) c[i] = c[i] * inv % P;
  }
}
inline vector<long long> operator*(const vector<long long> &x,
                                   const vector<long long> &y) {
  vector<long long> res, u = x, v = y;
  prework(u.size() + v.size() - 1);
  ntt(u, 1), ntt(v, 1);
  for (int i = 0; i < lim; i++) res.push_back(v[i] * u[i] % P);
  ntt(res, -1);
  res.resize(u.size() + v.size() - 1);
  return res;
}
vector<long long> mul(const vector<long long> &x, const vector<long long> &y) {
  return x * y;
}
vector<long long> getInv(vector<long long> x, int len) {
  x.resize(len);
  if (len == 1) {
    vector<long long> res;
    res.push_back(fpow(x[0], P - 2));
    return res;
  }
  vector<long long> y = getInv(x, (len + 1) >> 1);
  prework(len << 1);
  vector<long long> u = x, v = y, res;
  ntt(u, 1), ntt(v, 1);
  for (int i = 0; i < lim; i++)
    res.push_back(v[i] * (2LL - u[i] * v[i] % P + P) % P);
  ntt(res, -1);
  res.resize(len);
  return res;
}
inline void direv(vector<long long> &c) {
  for (int i = 0; i < (int)c.size() - 1; i++) c[i] = c[i + 1] * (i + 1) % P;
  c[c.size() - 1] = 0;
}
inline void integ(vector<long long> &c) {
  for (int i = (int)c.size() - 1; i > 0; i--)
    c[i] = c[i - 1] * fpow(i, P - 2) % P;
  c[0] = 0;
}
inline vector<long long> getLn(vector<long long> c) {
  vector<long long> a = getInv(c, (int)c.size());
  vector<long long> b = c;
  direv(b);
  vector<long long> res = b * a;
  res.resize(c.size());
  integ(res);
  return res;
}
vector<long long> getSqrt(vector<long long> x, int len) {
  x.resize(len);
  if (len == 1) {
    vector<long long> res;
    res.push_back(sqrt(x[0]));
    return res;
  }
  vector<long long> y = getSqrt(x, (len + 1) >> 1);
  vector<long long> u = x, v = y, w, res;
  w = getInv(y, len);
  prework(len << 1);
  ntt(u, 1), ntt(v, 1), ntt(w, 1);
  for (int i = 0; i < lim; i++)
    res.push_back((v[i] * v[i] % P + u[i]) % P * w[i] % P * inv2 % P);
  ntt(res, -1);
  res.resize(len);
  return res;
}
vector<long long> getExp(vector<long long> x, int len) {
  x.resize(len, 0);
  if (len == 1) {
    vector<long long> res;
    res.push_back(1);
    return res;
  }
  vector<long long> y = getExp(x, (len + 1) >> 1);
  vector<long long> u = x, v = y, w = y, res;
  w.resize(len, 0);
  w = getLn(w);
  prework(len << 1);
  u[0] = (u[0] + 1 - w[0] + P) % P;
  for (int i = 1; i < (int)u.size(); i++) u[i] = (u[i] - w[i] + P) % P;
  ntt(u, 1), ntt(v, 1);
  for (int i = 0; i < lim; i++) res.push_back(u[i] * v[i] % P);
  ntt(res, -1);
  res.resize(len);
  return res;
}
inline vector<long long> fpow(vector<long long> x, long long y, int n) {
  x = getLn(x);
  for (int i = 0; i < n; i++) x[i] = x[i] * y % P;
  x = getExp(x, n);
  return x;
}
inline vector<long long> getDiv(vector<long long> x, vector<long long> y) {
  vector<long long> u = x, v = y, res;
  reverse(u.begin(), u.end());
  reverse(v.begin(), v.end());
  int len = x.size() - y.size() + 1;
  u.resize(len, 0), v.resize(len, 0);
  res = getInv(v, len);
  res = mul(u, res);
  res.resize(len);
  reverse(res.begin(), res.end());
  return res;
}
inline vector<long long> getRest(vector<long long> x, vector<long long> y) {
  vector<long long> u = x, v = y, res = getDiv(x, y);
  v = mul(v, res);
  res = u;
  int len = max(u.size(), v.size());
  res.resize(len, 0), v.resize(len, 0);
  for (int i = 0; i < len; i++) res[i] = (res[i] - v[i] + P) % P;
  for (; !res.empty() && !res[res.size() - 1]; res.pop_back())
    ;
  return res;
}
}  // namespace Poly
const int maxn = 5000 + 10;
long long fac[maxn];
int main() {
  const long long mod = Poly::P;
  fac[0] = 1;
  for (int i = 1; i < maxn; ++i) fac[i] = fac[i - 1] * i % mod;
  int n, m, k;
  scanf("%d%d%d", &n, &m, &k);
  long long invm = Poly::fpow(m, mod - 2);
  vector<long long> a(maxn);
  a[1] = 1;
  a = Poly::getExp(a, maxn);
  for (auto &v : a) v = v * invm % mod;
  a[0] = ((a[0] + 1 - invm) % mod + mod) % mod;
  a = Poly::fpow(a, n, maxn);
  cout << a[k] * fac[k] % mod << endl;
  return 0;
}
