#include #pragma GCC optimize("Ofast,unroll-loops") #pragma GCC target("avx2,fma,bmi,bmi2,popcnt,lzcnt,tune=native") #include using namespace std; #define ll long long #define ull unsigned long long #define int128 __int128_t #define double long double // #define gcd __gcd // #define lcm(a, b) ((a)/gcd(a, b)*(b)) #define sqrt sqrtl #define log2 log2l #define log10 log10l #define floor floorl #define yes cout << "YES" #define no cout << "NO" #define trav(i, a) for (auto &i: (a)) #define all(a) (a).begin(), (a).end() #define rall(a) (a).rbegin(), (a).rend() #define sz(a) (int)a.size() #define Max(a) *max_element(all(a)) #define Min(a) *min_element(all(a)) #define Find(a, n) (find(all(a), n) - a.begin()) #define Count(a, n) count(all(a), n) #define Upper(a, n) (upper_bound(all(a), n) - a.begin()) #define Lower(a, n) (lower_bound(all(a), n) - a.begin()) #define next_perm(a) next_permutation(all(a)) #define prev_perm(a) prev_permutation(all(a)) #define sorted(a) is_sorted(all(a)) #define sum(a) accumulate(all(a), 0) #define sumll(a) accumulate(all(a), 0ll) #define Sort(a) sort(all(a)) #define Reverse(a) reverse(all(a)) #define Unique(a) Sort(a), (a).resize(unique(all(a)) - a.begin()) #define pb push_back #define eb emplace_back #define popcount __builtin_popcount #define popcountll __builtin_popcountll #define clz __builtin_clz #define clzll __builtin_clzll #define ctz __builtin_ctz #define ctzll __builtin_ctzll #define open(s) freopen(s, "r", stdin) #define write(s) freopen(s, "w", stdout) #define fileopen(s) open((string(s) + ".inp").c_str()), write((string(s) + ".out").c_str()); #define For(i, a, b) for (auto i = (a); i < (b); ++i) #define Fore(i, a, b) for (auto i = (a); i >= (b); --i) #define FOR(i, a, b) for (auto i = (a); i <= (b); ++i) #define ret(s) return void(cout << s); constexpr int mod = 1e9 + 7, mod2 = 998244353; constexpr double eps = 1e-9; const double PI = acos(-1); constexpr ull npos = string::npos; constexpr int dx[] = {1, 0, -1, 0, 1, 1, -1, -1}, dy[] = {0, 1, 0, -1, 1, -1, 1, -1}; using pii = pair; using pll = pair; using cd = complex; mt19937 mt(chrono::system_clock::now().time_since_epoch().count()); mt19937_64 mt64(chrono::system_clock::now().time_since_epoch().count()); typedef vector vi; typedef vector vvi; typedef vector vll; typedef vector vvll; typedef vector vdo; typedef vector vvdo; typedef vector vs; typedef vector vpair; typedef vector vvpair; typedef vector vb; typedef vector vvb; typedef vector vc; typedef vector vvc; typedef vector vcd; typedef priority_queue pq; typedef priority_queue> pqg; typedef priority_queue pqll; typedef priority_queue> pqgll; ll add(ll a, ll b, int m) {a = (a >= m ? a % m: a);b = (b >= m ? b % m: b);a+=b;return a >= m ? a - m: a;} ll sub(ll a, ll b, int m) {a = (a >= m ? a % m: a);b = (b >= m ? b % m: b);a-=b;return a < 0 ? a + m: a;} ll mul(ll a, ll b, int m) {a = (a >= m ? a % m: a);b = (b >= m ? b % m: b);return a*b % m;} ll bin_mul(ll a, ll b, ll m) {a = (a >= m ? a % m: a);b = (b >= m ? b % m: b);ll x = 0;while (b) {if (b & 1) x = (x + a) % m;a = (a + a) % m;b>>=1;}return x;} ll bin_pow(ll a, ll b, ll m) {ll x = 1;a = (a >= m ? a % m: a); while (b) {if (b & 1) x = bin_mul(x, a, m);a = bin_mul(a, a, m);b>>=1;}return x;} ll power(ll a, ll b, int m) {ll x = 1;a = (a >= m ? a % m: a); while (b) {if (b & 1) x = x*a % m;a = a*a % m;b>>=1;}return x;} ll power(ll a, ll b) {ll x = 1;while (b) {if (b & 1) x = x*a;a = a*a;b>>=1;}return x;} ll ceil(ll a, ll b) {return (a + b - 1)/b;} ll to_int(const string &s) {ll x = 0; for (int i = (s[0] == '-'); i < sz(s); ++i) x = x*10 + s[i] - '0';return x*(s[0] == '-' ? -1: 1);} bool is_prime(ll n) {if (n < 2) return 0;if (n < 4) return 1;if (n % 2 == 0 || n % 3 == 0) return 0;for (ll i = 5; i*i <= n; i+=6) {if(n % i == 0 || n % (i + 2) == 0) return 0;}return 1;} bool is_square(ll n) {ll k = sqrt(n); return k*k == n;} ll factorial(int n) {ll x = 1;for (int i = 2; i <= n; ++i) x*=i;return x;} ll factorial(int n, int m) {ll x = 1;for (ll i = 2; i <= n; ++i) x = x*i % m;return x;} bool is_power(ll n, ll k) {while (n % k == 0) n/=k;return n == 1ll;} string str(ll n) {if (n == 0) return "0"; string s = ""; bool c = 0; if (n < 0) c = 1, n = -n; while (n) {s+=n % 10 + '0'; n/=10;} if (c) s+='-'; Reverse(s); return s;} string repeat(const string &s, int n) {if (n < 0) return ""; string x = ""; while (n--) x+=s; return x;} string bin(ll n) {string s = ""; while (n) {s+=(n & 1) + '0'; n>>=1;} Reverse(s); return s;} void sieve(vector &a) {int n = a.size(); a[0] = a[1] = 0; for (int i = 4; i < n; i+=2) a[i] = 0; for (int i = 3; i*i < n; i+=2) {if (a[i]) {for (int j = i*i; j < n; j+=(i << 1)) a[j] = 0;}}} void sieve(bool a[], int n) {a[0] = a[1] = 0; for (int i = 4; i < n; i+=2) a[i] = 0; for (int i = 3; i*i < n; i+=2) {if (a[i]) {for (int j = i*i; j < n; j+=(i << 1)) a[j] = 0;}}} void sieve(vector &a) {int n = a.size(); for (int i = 2; i < n; i+=2) a[i] = 2; for (int i = 3; i*i < n; i+=2) {if (!a[i]) {for (int j = i; j < n; j+=(i << 1)) a[j] = i;}} for (int i = 3; i < n; i+=2) {if (!a[i]) a[i] = i;}} void sieve(int a[], int n) {for (int i = 2; i < n; i+=2) a[i] = 2; for (int i = 3; i*i < n; i+=2) {if (!a[i]) {for (int j = i; j < n; j+=(i << 1)) a[j] = i;}} for (int i = 3; i < n; i+=2) {if (!a[i]) a[i] = i;}} vector factorize(int n) {vector a; for (int i = 2; i*i <= n; ++i) {if (n % i == 0) {int k = 0; while (n % i == 0) ++k, n/=i; a.emplace_back(i, k);}} if (n > 1) a.emplace_back(n, 1); return a;} int rand(int l, int r) {return uniform_int_distribution(l, r)(mt);} ll rand(ll l, ll r) {return uniform_int_distribution(l, r)(mt64);} int Log2(int n) {return 31 - __builtin_clz(n);} ll Log2(ll n) {return 63 - __builtin_clzll(n);} template void compress(vector &a) {vector b; for (T &i: a) b.push_back(i); sort(all(b)); b.resize(unique(all(b)) - b.begin()); for (T &i: a) i = lower_bound(all(b), i) - b.begin() + 1;} template bool ckmin(A &a, const B &b) {return a > b ? a = b, 1: 0;} template bool ckmax(A &a, const B &b) {return a < b ? a = b, 1: 0;} template istream& operator>>(istream& in, pair &p) {in >> p.first >> p.second; return in;} template ostream& operator<<(ostream& out, const pair &p) {out << p.first << ' ' << p.second; return out;} template istream& operator>>(istream& in, vector &a) {for (auto &i: a) in >> i; return in;} template ostream& operator<<(ostream& out, const vector &a) {for (auto &i: a) out << i << ' '; return out;} template istream& operator>>(istream& in, vector> &a) {for (auto &i: a) in >> i; return in;} template ostream& operator<<(ostream& out, const vector> &a) {for (auto &i: a) out << i << '\n'; return out;} template istream& operator>>(istream& in, deque &a) {for (auto &i: a) in >> i; return in;} template ostream& operator<<(ostream& out, const deque &a) {for (auto &i: a) out << i << ' '; return out;} // istream& operator>>(istream& in, __int128_t &a) {string s; in >> s; a = 0; for (int i = (s[0] == '-'); i < sz(s); ++i) a = a*10 + s[i] - '0'; a*=(s[0] == '-' ? -1: 1); return in;} // ostream& operator<<(ostream& out, __int128_t a) {string s = ""; if (a < 0) out << '-', a = -a; if (a == 0) s+='0'; while (a > 0) {s+=(int)(a % 10) + '0'; a/=10;} Reverse(s); out << s; return out;} template class Mint { using S = decltype(P_); static_assert(is_same_v || is_same_v); static_assert(P_ & 1 && 0 < P_ && P_ < ((S)1 << (sizeof(S) * 8 - 2))); using U = conditional_t, unsigned, unsigned long long>; using D = conditional_t, unsigned long long, __uint128_t>; inline constexpr static U uinv(U x) {U y = x; for(int i = is_same_v ? 4 : 5; i--;) y *= 2 - x * y; return y;} constexpr static U P = P_, P2 = P << 1, R = -uinv(P), R2 = -(D)P % P; static_assert(P * R == -1); inline constexpr static U reduce(D x) {return (x + (U)x * R * (D)P) >> (sizeof(U) * 8);} inline constexpr Mint(U x, int) : v(x) {} U v; public: inline constexpr static S mod() {return P;} inline constexpr Mint() : v(0) {} inline constexpr Mint(const Mint &x) : v(x.v) {} template::is_integer, int> = 0> inline constexpr Mint(T x) : v(reduce((D)R2 * (numeric_limits::is_signed && x < 0 ? ((x + P < 0) && (x %= P), x + P) : ((sizeof(T) > sizeof(U) && x >= (T)1 << sizeof(U)) && (x %= P), x)))) {} inline constexpr S val() const {U x = reduce(v); return (x - P) >> (sizeof(U) * 8 - 1) ? x : x - P;} template::is_integer, int> = 0> explicit inline constexpr operator T() const {return val();} inline constexpr friend bool operator==(const Mint &x, const Mint &y) {return x.val() == y.val();} inline constexpr friend bool operator!=(const Mint &x, const Mint &y) {return x.val() != y.val();} inline constexpr Mint &operator=(const Mint &x) & {v = x.v; return *this;} inline constexpr Mint &operator++() & {return *this += 1;} inline constexpr Mint operator++(int) & {Mint x = *this; *this += 1; return x;} inline constexpr Mint &operator--() & {return *this -= 1;} inline constexpr Mint operator--(int) & {Mint x = *this; *this -= 1; return x;} inline constexpr Mint operator-() const {return Mint(v ? P2 - v : 0, 0);} inline constexpr Mint &operator+=(const Mint &x) & {v += x.v, (v - P2) >> (sizeof(U) * 8 - 1) || (v -= P2); return *this;} inline constexpr Mint &operator-=(const Mint &x) & {v -= x.v, v >> (sizeof(U) * 8 - 1) && (v += P2); return *this;} inline constexpr Mint &operator*=(const Mint &x) & {v = reduce((D)v * x.v); return *this;} inline constexpr Mint &operator/=(const Mint &x) & {return *this *= x.inv();} inline constexpr friend Mint operator+(Mint x, const Mint &y) {return x += y;} inline constexpr friend Mint operator-(Mint x, const Mint &y) {return x -= y;} inline constexpr friend Mint operator*(Mint x, const Mint &y) {return x *= y;} inline constexpr friend Mint operator/(Mint x, const Mint &y) {return x /= y;} template::is_integer, int> = 0> inline constexpr Mint qpow(T y) const {Mint x = *this, z = 1; while(y) {if(y & 1) z *= x; if(y >>= 1) x *= x;} return z;} template::is_integer, int> = 0> inline constexpr friend Mint qpow(const Mint &x, T y) {return x.qpow(y);} inline constexpr Mint inv() const {return qpow(P - 2);} inline constexpr friend Mint inv(const Mint &x) {return x.inv();} inline friend istream &operator>>(istream &is, Mint &x) {S y; is >> y, x = y; return is;} inline friend ostream &operator<<(ostream &os, const Mint &x) {return os << x.val();} }; using mint = Mint; int phi(int n) { int x = n; for (int i = 2; i*i <= n; ++i) if (n % i == 0) { x-=x/i; while (n % i == 0) n/=i; } if (n > 1) x-=x/n; return x; } int main() { ios_base::sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL); cout << fixed << setprecision(10); int n, m, k; cin >> n >> m >> k; mint x = 0; vi a, b; for (int i = 1; i*i <= n; ++i) if (n % i == 0) { a.pb(i); if (i*i < n) a.pb(n/i); } for (int i = 1; i*i <= m; ++i) if (m % i == 0) { b.pb(i); if (i*i < m) b.pb(m/i); } vi c(sz(a)), d(sz(b)); For(i,0,sz(a)) c[i] = phi(a[i]); For(i,0,sz(b)) d[i] = phi(b[i]); if (sz(a) & 1) c.pb(c.back()); if (sz(b) & 1) d.pb(d.back()); For(i,0,sz(a)) For(j,0,sz(b)){ x+=mint(k).qpow(a[i]*b[j]*gcd(n/a[i], m/b[j]))*c[i^1]*d[j^1]; } cout << x/(n*m); cerr << "\nProcess returned 0 (0x0) execution time : " << 1.0*clock()/CLOCKS_PER_SEC << " s"; return 0; }