import std.conv, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.container, std.math, std.range, std.regex, std.typecons;
import core.bitop;

class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; }
int readInt() { return readToken().to!int; }
long readLong() { return readToken().to!long; }
real readReal() { return readToken().to!real; }

void chmin(T)(ref T t, in T f) { if (t > f) t = f; }
void chmax(T)(ref T t, in T f) { if (t < f) t = f; }

int binarySearch(T)(in T[] as, in bool delegate(T) test) { int low = -1, upp = cast(int)(as.length); for (; low + 1 < upp; ) { int mid = (low + upp) >> 1; (test(as[mid]) ? low : upp) = mid; } return upp; }
int lowerBound(T)(in T[] as, in T val) { return as.binarySearch((T a) => (a < val)); }
int upperBound(T)(in T[] as, in T val) { return as.binarySearch((T a) => (a <= val)); }


immutable MO = 10L^^9 + 7;
immutable LIM = 2 * 10^^7 + 10;

long[] inv, fac, invFac;
void prepare() {
  inv = new long[LIM];
  fac = new long[LIM];
  invFac = new long[LIM];
  inv[1] = 1;
  foreach (i; 2 .. LIM) {
    inv[i] = MO - (MO / i) * inv[cast(size_t)(MO % i)] % MO;
  }
  fac[0] = invFac[0] = 1;
  foreach (i; 1 .. LIM) {
    fac[i] = fac[i - 1] * i % MO;
    invFac[i] = invFac[i - 1] * inv[i] % MO;
  }
}

int M, N, K;

void main() {
  // prepare();
  
  try {
    for (; ; ) {
      M = readInt();
      N = readInt();
      K = readInt();
      debug {
        writefln("M = %s, N = %s, K = %s", M, N, K);
      }
      
      /*
      long ans;
      foreach (a; 0 .. M + 1) foreach (b; 0 .. N + 1) {
        if (1 <= a + b && a + b <= K) {
          long prod = 1;
          (prod *= fac[a + b]) %= MO;
          (prod *= invFac[a]) %= MO;
          (prod *= invFac[b]) %= MO;
          (prod *= fac[M]) %= MO;
          (prod *= invFac[M - a]) %= MO;
          (prod *= fac[N]) %= MO;
          (prod *= invFac[N - b]) %= MO;
          (prod *= (a + 1)) %= MO;
          (prod *= (b + 1)) %= MO;
          (prod *= fac[M + N - a - b]) %= MO;
          (prod *= invFac[M + N - K]) %= MO;
          (ans += prod) %= MO;
if(M<=2)writeln(a," ",b," ",prod);
        }
      }
      writeln(ans);
      */
      
      long ans;
      // x = y = 0
      {
        long p = 1;
        foreach (i; 0 .. K) {
          (p *= ((M + N) - i)) %= MO;
        }
        long sum = K;
        (sum *= p) %= MO;
        debug {
          writefln("  x = 0, y = 0: %s", sum);
        }
        (ans += sum) %= MO;
      }
      // x = 0, y > 0 or x > 0, y = 0
      {
        long p = 1;
        foreach (i; 0 .. K - 1) {
          (p *= ((M + N - 1) - i)) %= MO;
        }
        long sum;
        foreach (k; 0 .. K) {
          (sum += (K - k)) %= MO;
        }
        sum %= MO;
        (sum *= p) %= MO;
        debug {
          writefln("  x = 0, y > 0 or x > 0, y = 0: %s", sum);
        }
        (sum *= (M + N)) %= MO;
        (ans += sum) %= MO;
      }
      // x > 0, y > 0
      {
        long p = 1;
        foreach (i; 0 .. K - 2) {
          (p *= ((M + N - 2) - i)) %= MO;
        }
        long sum;
        foreach (k; 0 .. K) {
          (sum += 1L * (K - k) * k) %= MO;
        }
        (sum *= 2) %= MO;
        (sum *= p) %= MO;
        debug {
          writefln("  x > 0, y > 0: %s", sum);
        }
        (sum *= M) %= MO;
        (sum *= N) %= MO;
        (ans += sum) %= MO;
      }
      writeln(ans);
    }
  } catch (EOFException e) {
  }
}


Measured memory_bytes: 256