#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 998244353;
LL pw(LL n, int x) {
	LL ret = 1;
	LL t = n;
	while (x) {
		if (x & 1) ret = ret * t % mod;
		t = t * t % mod;
		x >>= 1;
	}
	return ret;
}

int main() {
	int n, m, k;
	scanf("%d%d%d", &n, &m, &k);
	if (n == 1)
		printf("%lld", pw(k, m));
	else if (m == 1)
		printf("%lld", pw(k, n));
	else {
		LL ret = 0;
		for (int i = 1; i <= k; ++i)
			ret = ((pw(i, n) - pw(i - 1, n) + mod) % mod * pw(k + 1 - i, m) % mod + ret) % mod;
		printf("%lld", ret);
	}
}
#include<bits/stdc++.h>
using namespace std; 
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i < (int)(n); i++)
#define length size()
#define int long long
#define ll long long
#include <cstdint>
long long modpow(long long a, long long n, long long mod) {
    long long res = 1;
    if(n==0) return 0;
    while (n > 0) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}
const int MOD = 1000000007;
const int mod = 998244353;
const int MAX = 510000;
const int inf = 400000000000000;
template<typename T> string join(vector<T> &vec ,const string &sp){
    int si = vec.length;
    if(si==0){
        return "";
    }else{
        stringstream ss;
        rep(i,si-1){
            ss << vec[i] << sp;
        }
        ss << vec[si - 1];
        return ss.str();
    }
}
vector<vector<int>> ruiseki2d(vector<vector<int>> vec){
    rep(i,vec.size()-1){
        rep(j,vec[0].size()-1){
            vec[i+1][j+1] = vec[i][j+1]+vec[i+1][j]-vec[i][j]+vec[i+1][j+1];
        }
    }
    return vec;
}
class CompareDist
{
public:
    bool operator()(pair<int,int> p,pair<int,int>q){
    return p.second > q.second;
}
};
vector<int> dijkstra(vector<vector<pair<int,int>>> vec,int s){
    priority_queue<pair<int,int>,vector<pair<int,int>>,CompareDist> que;
    pair<int,int> f = make_pair(s,0);//point,cost;
    que.push(f);
    bool y = false;
    vector<int> cost(vec.size(),inf);
    while(!que.empty()){
        pair<int,int> tmp = que.top();
        que.pop();
        int p = tmp.first;
        int c = tmp.second;
        if(cost[p]>c){
        cost[p] = c;
        rep(i,vec[p].size()){
            if(cost[vec[p][i].first]<=inf){
            tmp = make_pair(vec[p][i].first,vec[p][i].second+c);
            que.push(tmp);
            }
        }
        }
        if(!y) cost[p] = inf;
        y = true;
    }
    return cost;
}
signed main(void){
    int n,m,k;
    cin >> n >> m >> k;
    int ans = 0;
    if(n==1||m==1) ans = modpow(k,max(n,m),mod);
    else{
        for(int i=1;i<=k;i++){
            ans += (modpow(i,n,mod)*modpow(k-i+1,m,mod)%mod);
            ans %= mod;
            ans -= (modpow(i,n,mod)*modpow(k-i,m,mod)%mod);
            ans = (ans%mod+mod)%mod;
            //cout << modpow(i,n,mod) << " " << modpow(k-i+1,m,mod) << endl;
        }
    }
    cout << ans%mod << endl;
}
