// !Start && !End 
//  0 se divide

// { Tu jab paida hua tha na tabhi ye code likh diya tha --Ranvijay }

#pragma optimise GCC(-O2)
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define ld long double
#define pii pair<ll,ll>
#define ve(x) vector<x>
#define f(a,b,c) for(ll a=b;a<c;a++)
#define foto(x,v) for(auto x:v)
#define read(t) ll t; cin>>t;
#define reads(t) string t; cin>>t;
#define readarr(arr,n) ll arr[n]; f(i,0,n) cin>>arr[i];
#define forstl(i,v) for(auto &i: v)
#define ln endl
#define Endl endl
#define dbg(x) cout<<#x<<" = "<<x<<ln;
#define dbg2(x,y) cout<<#x<<" = "<<x<<" & "<<#y<<" = "<<y<<ln;
#define dbgstl(v) cout<<#v<<" = \n"; { int c=0; forstl(it,v) \
cout<<"    Term "<< ++c <<" = "<<it<<ln;} cout<<ln;
#define dbgstlp(v) cout<<#v<<" = \n"; { int c=0; forstl(it,v) \
cout<<"    Term "<< ++c <<" = "<<it.fi<<" , "<<it.se<<ln;} cout<<ln;
#define dbgarr(v,s,e) cout<<#v<<" = "; f(i,s,e) cout<<v[i]<<", "; cout<<ln;
#define addEdge(tr,k) f(i,0,k) { ll x,y; cin>>x>>y, tr[x].push_back(y), tr[y].push_back(x);}
#define all(v) v.begin(),v.end()

mt19937_64 rang(chrono::high_resolution_clock::now().time_since_epoch().count());
int rng(int lim) { uniform_int_distribution<int> uid(0, lim - 1); return uid(rang); }

//														GLOBAL VARS
ll INF =LLONG_MAX;
const ll M= 998244353;

//														USEFUL FUNCTIONS
ll powm(ll ,ll);

//                                                      DSU 
// vector<int> parent, rank;
// void make_set(int v) { parent[v] = v; rank[v] = 0;}
// int find_set(int v) { if (v == parent[v]) return v; return parent[v] = find_set(parent[v]);}
// void union_sets(int a, int b) { a = find_set(a);  b = find_set(b); if (a != b) { if (rank[a] < rank[b]) swap(a, b); parent[b] = a; if (rank[a] == rank[b]) rank[a]++; }}

//                                                     LCA by Binary Lifting      l=ceil(log2(n)) dfs(root,root)
// ll dp[200005][21] ; ve(ll) tin(200005), tout(200005); ll tim = 0 , l;
// void dfs(int n , int par ){  tin[n] = ++tim; dp[n][0] = par; f(i,1,l+1) dp[n][i] = dp[dp[n][i-1]][i-1];
//    foto(x,tr[n]) if(x==par) continue; else dfs(x , n);        tout[n] = ++tim;  }
// bool is_ancestor(ll u , ll v) { return tin[u]<=tin[v] && tout[u]>=tout[v] ;}1
// ll lca(ll u , ll v){ if(is_ancestor(u,v)) return u ; if(is_ancestor(v,u)) return v;
//    for(int j = l ; j>=0 ; j--) if(!is_ancestor(dp[u][j] , v)) u = dp[u][j];    return dp[u][0];}


ll fact[200005];

// 														MAIN
int32_t main()
{ 
	ios_base::sync_with_stdio(false);
    cin.tie(NULL);
	cout.tie(NULL);
    //It gets easier day by day, but the hard part is to........
    read(n) read(m) read(k)
    ll ans = 0;
    fact[0] = 1;
    f(i,1,200005) fact[i] = fact[i-1]*i %M;
    f(i,0,k+1)
    {
        ll len_to_operate = n - i;
        ll c = powm(m-1 , len_to_operate - 1);
        c*= m;
        c%=M;
        ll ncc = fact[n-1];
        ncc *= powm(fact[i] , M-2);
        ncc%=M;
        ncc *= powm(fact[n-1-i] , M-2);
        ncc%=M;
        // dbg2(c,ncc)
        c*=ncc;
        c%=M;
        ans += c;
        ans%=M;
    }
    cout<<ans;
}










//													FUNCTIONS DECLARATIONS
ll powm(ll a, ll b) {
	ll res=1;
	while(b) {
		if(b&1)
			res=(res*a)%M;
		a=(a*a)%M;
		b>>=1;
	}
	return res;
}


Measured memory_bytes: 5220