#include <cstdio>

using u32 = unsigned int;
using u64 = unsigned long long int;

constexpr u32 mod = 998244353;

int n, m, k;

/*
A1 ... AN
B1 ... BM

Bmin >= Amax
*/

u32 modpow(u32 a, u32 n){
  u32 r = 1;
  for(; n; n>>=1){
    if(n&1) r = (u64) r * a % mod;
    a = (u64) a * a % mod;
  }
  return r;
}


int main(){
  scanf("%d%d%d", &n, &m, &k);

  u64 ans = 0;

  if(n == 1){
    for(int i = 1; i <= k; i++){
      ans += modpow(k - i + 1, m) - modpow(k - i, m) + mod;
    }
  }
  else if(m == 1){
    for(int i = 1; i <= k; i++){
      ans += modpow(i, n) - modpow(i - 1, n) + mod;
    }
  }
  else {
    for(int i = 1; i <= k; i++){
      ans += (u64) (modpow(i, n) - modpow(i-1, n) + mod) * modpow(k - i + 1, m) % mod;
    }
  }

  printf("%llu\n", ans % mod);
  

  return 0;
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
#include <functional>
#include <chrono>

#define int long long
#define ld long double
#define db double
#define endl "\n"
#define pb push_back
#define mp make_pair
#define all(x) x.begin(), x.end()

using namespace __gnu_pbds; 
using namespace std;
using namespace chrono;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
template<typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

void deb_out() { 
    cout << endl; 
}
template <typename Head, typename... Tail>
void deb_out(Head H, Tail... T) {
    cout << " " << H;
    deb_out(T...);
}
#ifdef LOCAL
    #define deb(...) cout << "[" << #__VA_ARGS__ << "]:", deb_out(__VA_ARGS__);
#else
    #define deb(...) ;
#endif

const long double PI = 3.14159265358979323846264338;
const long long INF = 1000000000000000000;
const long long INF1 = 1000000000;
// const long long MOD = 1000000007;
const long long MOD = 998244353;

inline int cl(int a, int b){
    if(a % b)
        return 1 + a / b;
    return a / b;
}
        
int mpow(int a, int b){
    a %= MOD;
    if(!b)
        return 1;
    int temp = mpow(a, b / 2);
    temp = (temp * temp) % MOD;
    if(b % 2)
        return (a * temp) % MOD;
    return temp;
}
int _pow(int a, int b){
    if(!b)
        return 1;
    int temp = _pow(a, b / 2);
    temp = (temp * temp);
    if(b % 2)
        return (a * temp);
    return temp;
}
inline int mod_in(int n){
    return mpow(n, MOD - 2);
}

const int N = 2e5 + 5;
int fct[N], infct[N];

void pre() {
    fct[0] = 1;
    infct[0] = mod_in(1);
    for (int i = 1 ; i < N ; i++) {
        fct[i] = (i * fct[i - 1]) % MOD;
        infct[i] = mod_in(fct[i]);
    }
}

int nCr(int n, int r) {
    if (n < r)
        return 0;
    int v = (fct[n] * infct[n - r]) % MOD;
    v *= infct[r];
    return v % MOD;
}

int put(int n, int r) {
    if (r < 1)
        return 0;
    return nCr(n + r - 1, r - 1);
}

int32_t main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int Tests = 1;
    // cin >> Tests;
    pre();
    while (Tests--) {
        int n, m, k;
        cin >> n >> m >> k;

        int ans = 0;

        ans = 0;
        if (n == 1) {
            ans = mpow(k, m);
            cout << ans;
            exit(0);
        } else if (m == 1) {
            ans = mpow(k, n);
            cout << ans;
            exit(0);
        }
        deb(ans)
        for (int i = 1 ; i <= k ; i++) {
            int lss = mpow(i, n);
            if (i > 1)
                lss -= mpow(i - 1, n);
            lss = (lss + MOD) % MOD;
            // int more = mpow(m, k - i + 1);
            // deb(i, lss, mpow(k - i + 1, m));
            lss *= mpow(k - i + 1, m);
            ans += lss % MOD;
            ans %= MOD;
            // deb(i, ans)
        }

        // int ans = put(n + m, k);
        cout << ans << endl;
    }
}

