#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<bitset>
#include<cstring>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<deque>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#include<string>
#include<sstream>
#include<chrono>
#include<random>
#include<unordered_map> 
#include<ctype.h>
#include<cassert>
#include<numeric>
#include<functional>
using namespace std;
typedef long long ll; typedef std::pair<ll, ll> pll; typedef std::pair<int, int> pii; typedef unsigned long long ull; typedef long double ldb; typedef double db;
#define pb push_back
#define eb emplace_back
#define all(a) (a).begin(),(a).end()
template <class output_type, class input_type>
output_type Convert(const input_type& input) {
	stringstream ss; output_type result;
	ss.clear(); ss << input; ss >> result;
	return result;
}
const double Pi = acos(-1.0); const int inf = 0x3f3f3f3f, Mod = 1e9+7, N = 5e5 + 3; const ll INF = 1ll << 60;
inline ll qpow(ll a, ll b, ll mod = Mod, ll ans = 1) {
	while (b) {
		if (b & 1)ans = ans * a % mod;
		a = a * a % mod; b >>= 1;
	}return ans;
}
ll gcd(ll a, ll b) { return (b ? gcd(b, a % b) : a); }; ll lcm(ll a, ll b) { return a * b / (gcd(a, b)); }
pii EXgcd(int x, int y) {        //return.first ny
	if (!y) { return { 1,0 }; }pii a = EXgcd(y, (x + y) % y);
	return { a.second, a.first - a.second * (x / y) };
}
inline bool Ezisprime(int n){
	if (n <= 1)return 0;if (n <= 3)return 1;
	vector<int> ezp{ 5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97 };
	for (int i = 0; i < ezp.size(); i++)if (n == ezp[i])return 1;
	for (int i = 2; i <= sqrt(n); i++)if (n % i == 0)return 0;
	return 1;
}
inline int LIS(const vector<int> Origins, const int n){
	if (!n || !Origins.size()) return 0;
	int len = 0; vector<int> d(n, 0); d[0] = Origins[0];
	for (int i = 1; i < n; i++)
		if (Origins[i] >= d[len])d[++len] = Origins[i];
		else d[upper_bound(d.begin(), d.begin() + len, Origins[i]) - d.begin()] = Origins[i];
	return len + 1;
}
struct edge {ll to, cost, time;}; typedef vector<vector<edge>> Graph;
inline vector<ll> Dijkstra(const Graph& G, ll s)// G为路表，s为起点，结果为各点距离容器
{
	priority_queue<pll, vector<pll>, greater<pll> >q;   //first 为距离，second 为点号
	vector<ll> d(G.size(), INF);
	d[s] = 0;q.push({ 0,s });
	while (!q.empty()){
		pll tp = q.top(); q.pop();
		if (d[tp.second] < tp.first)continue;
		for (auto& e : G[tp.second]){
			if (e.cost + d[tp.second] < d[e.to]){
				d[e.to] = e.cost + d[tp.second];
				q.push({ d[e.to], e.to });
			}
		}
	}
	return d;
}
inline int Alptonum(const char a) { if (a <= 'z')return int(a - 'a'); else return int(a - 'A'); }
inline char Numtoalp(const int n, bool t) { if (!t)return char('a' + n); else return char('A' + n); }
inline bool cmp(pii a, pii b) {  //default more and more larger
	return a.first < b.first;
}
struct cmpstl {           //reverse
	inline bool operator()(pii a, pii b) {
		if (a.second == b.second)return a.first > b.first;
		return a.second < b.second;
	}
};
//partial_sum(begin,end,place,minus<int>()) adjacent_differece(begin,end,place) 
//count(begin(),end(),char=='x') count_if(begin(),end(),boolcmp) vector<int> p(n);iota(p.begin(), p.end(), 0);

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| Code follows ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\\
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV Code follows VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVII
db dp[1001][1001];

int main()
{
	ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
	int n; cin >> n;
//	int ts; cin >> ts;
	double res = 0;
	for (int i = 1; i < n; i++)res += double(n) / i;
	cout << setprecision(11) << fixed << res << '\n';
	
}
/*


*/
#include<bits/stdc++.h>
using namespace std;
#define I inline int
#define V inline void
#define ll long long int
#define isnum(ch) ('0'<=ch&&ch<='9')
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ROF(i,a,b) for(int i=a;i>=b;i--)
#define REP(u) for(int i=h[u],v;v=e[i].t,i;i=e[i].n)
#define gc (_op==_ed&&(_ed=(_op=_buf)+fread(_buf,1,100000,stdin),_op==_ed)?EOF:*_op++)
char _buf[100000],*_op(_buf),*_ed(_buf);
I getint(){
	int _s=0,_f=1;char _ch=gc;
	while(!isnum(_ch))(_ch=='-')&&(_f=-1),_ch=gc;
	while(isnum(_ch))_s=_s*10+_ch-48,_ch=gc;
	return _s*_f;
}
const int N=5e5+2,mod=998244353;
V check(int&x){x-=mod,x+=x>>31&mod;}
V cmax(int&x,int y){if(x-y>>31)x=y;}
V cmin(int&x,int y){if(y-x>>31)x=y;}
I Pow(ll t,int x,ll s=1){
	for(;x;x>>=1,t=t*t%mod)if(x&1)s=s*t%mod;
	return s;
}
char a[N];
int n,cnt[26],m,k,ans;
V input(){
	n=getint(),m=getint(),k=getint();
	if(n==1||m==1)ans=Pow(k,n*m);
	else FOR(i,1,k)
		check(ans+=1ll*Pow(i,n)*(Pow(k-i+1,m)-Pow(k-i,m)+mod)%mod);
	cout<<ans;
}
V init(){
	
}
V work(){
	
}
int main(){
		input();
		init();
		work();
//	}
	return 0;
}