Problem:
Score : 500 points

Problem Statement

We have a grid of squares with N rows and M columns. Let (i, j) denote the square at the i-th row from the top and j-th column from the left. We will choose K of the squares and put a piece on each of them.

If we place the K pieces on squares (x_1, y_1), (x_2, y_2), ..., and (x_K, y_K), the cost of this arrangement is computed as:

\sum_{i=1}^{K-1} \sum_{j=i+1}^K (|x_i - x_j| + |y_i - y_j|)

Find the sum of the costs of all possible arrangements of the pieces. Since this value can be tremendous, print it modulo 10^9+7.

We consider two arrangements of the pieces different if and only if there is a square that contains a piece in one of the arrangements but not in the other.

Constraints

2 \leq N \times M \leq 2 \times 10^5

2 \leq K \leq N \times M

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N M K

Output

Print the sum of the costs of all possible arrangements of the pieces, modulo 10^9+7.

Sample Input 1

2 2 2

Sample Output 1

8

There are six possible arrangements of the pieces, as follows:

((1,1),(1,2)), with the cost |1-1|+|1-2| = 1

((1,1),(2,1)), with the cost |1-2|+|1-1| = 1

((1,1),(2,2)), with the cost |1-2|+|1-2| = 2

((1,2),(2,1)), with the cost |1-2|+|2-1| = 2

((1,2),(2,2)), with the cost |1-2|+|2-2| = 1

((2,1),(2,2)), with the cost |2-2|+|1-2| = 1

The sum of these costs is 8.

Sample Input 2

4 5 4

Sample Output 2

87210

Sample Input 3

100 100 5000

Sample Output 3

817260251

Be sure to print the sum modulo 10^9+7.

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

// ライブラリ
#include<vector>
// 補助関数
template<typename T> T modpow(T x, T p, T M) {
  if(!p) return 1;
  if(p & 1) return (x * modpow(x, p - 1, M)) % M;
  return modpow((x * x) % M, p >> 1, M);
}
// 剰余類
template<typename T, T M = T(1e9 + 7)>
struct ModInt {
  T number;
  ModInt(T n = 0) : number(n % M) {while(number < 0) number += M;}
  // 代入演算
  ModInt& operator+=(const ModInt& m) {return *this = *this + m;}
  ModInt& operator-=(const ModInt& m) {return *this = *this - m;}
  ModInt& operator*=(const ModInt& m) {return *this = *this * m;}
  ModInt& operator/=(const ModInt& m) {return *this = *this / m;}
  ModInt& operator%=(const ModInt& m) {return *this = *this % m;}
  // 二項演算
  friend const ModInt operator+(const ModInt& lhs, const ModInt& rhs) {return lhs.number + rhs.number;}
  friend const ModInt operator-(const ModInt& lhs, const ModInt& rhs) {return lhs.number - rhs.number;}
  friend const ModInt operator*(const ModInt& lhs, const ModInt& rhs) {return lhs.number * rhs.number;}
  friend const ModInt operator/(const ModInt& lhs, const ModInt& rhs) {return lhs.number * modpow(rhs.number, M - 2, M);}
  friend const ModInt operator%(const ModInt& lhs, const ModInt& rhs) {return lhs.number % rhs.number;}
  // 関係演算
  friend bool operator==(const ModInt& lhs, const ModInt& rhs) {return lhs.number == rhs.number;}
  friend bool operator!=(const ModInt& lhs, const ModInt& rhs) {return lhs.number != rhs.number;}
  friend bool operator<=(const ModInt& lhs, const ModInt& rhs) {return lhs.number <= rhs.number;}
  friend bool operator>=(const ModInt& lhs, const ModInt& rhs) {return lhs.number >= rhs.number;}
  friend bool operator<(const ModInt& lhs, const ModInt& rhs) {return lhs.number < rhs.number;}
  friend bool operator>(const ModInt& lhs, const ModInt& rhs) {return lhs.number > rhs.number;}
  // 組み合わせ
  friend ModInt combination(const ModInt& n, const ModInt& r) {
    static std::vector<T> fact{1, 1}, inv{1, 1}, finv{1, 1};
    if(n < r) return 0;
    if(n < 0 || r < 0) return 0;
    for(T i = fact.size(); i <= n; ++i) {
      fact.emplace_back(fact.back() * i % M);
      inv.emplace_back(inv.at(M % i) * (M - M / i) % M);
      finv.emplace_back(finv.back() * inv.back() % M);
    }
    return (fact.at(n.number) * finv.at((n - r).number) % M) * finv.at(r.number) % M;
  }
};
// 入出力ストリーム
#include<iostream>
template<typename T, T M> inline std::istream& operator>>(std::istream& is, ModInt<T, M>& m) {return is >> m.number;}
template<typename T, T M> inline std::ostream& operator<<(std::ostream& os, const ModInt<T, M>& m) {return os << m.number;}

#include<bits/stdc++.h>
using namespace std;

int main() {
  using I = ModInt<long long, (long long)(1e9 + 7)>;

  I H, W, K;
  cin >> H >> W >> K;

  vector<vector<I>> s(H.number+1, vector<I>(W.number+1));
  for(auto h=1; h<=H; ++h) for(auto w=1; w<=W; ++w) s[h][w] += h + w - 1;
  for(auto h=1; h<=H; ++h) for(auto w=1; w<=W; ++w) s[h][w] += s[h-1][w] + s[h][w-1] - s[h-1][w-1];

  I res = 0;
  I pair = combination(H*W-2, K-2);
  for(auto h=1; h<=H; ++h) for(auto w=1; w<=W; ++w) {
    res += pair * s[(H-h+1).number][(W-w).number];
    res += pair * s[(H-h).number][(W-w+1).number];
  }
  cout << res << endl;
}