#include <bits/stdc++.h>
using namespace std;
int A, B, C;
const int Sieve = 0x3FFFFFFF;
int rid[2010], r0;
struct Memoblock {
  int V[150];
  void clear() {
    int i;
    for (i = 1; i <= r0; i++) V[i] = -1;
  }
};
void code_id_in_block() {
  int i;
  r0 = 0;
  for (i = 1; i <= C; i++) rid[i] = 0;
  for (i = 1; i <= C; i++)
    if (rid[C / i] == 0) rid[C / i] = ++r0;
}
int cob[4000002], uob[4000002], bs0;
void code_out_of_block() {
  int i, j, F = A * B;
  for (i = 1; i <= F; i++) cob[i] = uob[i] = 0;
  bs0 = 0;
  for (i = 1; i <= A; i++)
    for (j = 1; j <= B; j++) {
      uob[i * j]++;
      if (cob[i * j] == 0) cob[i * j] = ++bs0;
    }
}
Memoblock* M[2000001];
int P[2000010], Div[4000010], lyr[4000010], core[4000010];
int D[4000010], prd[2010];
void Eusieve(int N) {
  int i, j;
  Div[1] = lyr[1] = P[0] = 0;
  for (i = 2; i <= N; i++) Div[i] = i;
  for (i = 2; i <= N; i++) {
    if (Div[i] == i) {
      lyr[i] = core[i] = 1;
      P[++P[0]] = i;
    }
    for (j = 1; j <= P[0]; j++) {
      if (i * P[j] > N) break;
      Div[i * P[j]] = P[j];
      if (i % P[j] == 0) {
        lyr[i * P[j]] = lyr[i] + 1;
        core[i * P[j]] = core[i];
        break;
      } else {
        lyr[i * P[j]] = 1;
        core[i * P[j]] = i;
      }
    }
  }
  D[1] = 1;
  for (i = 2; i <= N; i++) D[i] = (lyr[i] + 1) * D[core[i]];
  prd[0] = 0;
  for (i = 1; i <= C; i++) prd[i] = prd[i - 1] + D[i];
}
void initialize() {
  int i;
  for (i = 1; i <= bs0; i++) M[i] = NULL;
  Eusieve(max(A * B, C));
}
bool Call_memory(int a, int b, int& r) {
  if (M[cob[a]] == NULL) return false;
  r = M[cob[a]]->V[rid[b]];
  return (r >= 0);
}
void Set_memory(int a, int b, int r) {
  if (M[cob[a]] == NULL) {
    M[cob[a]] = new Memoblock;
    M[cob[a]]->clear();
  }
  M[cob[a]]->V[rid[b]] = r;
}
int i;
int Sd(int r, int k) {
  int ans;
  if (r == 0) return 0;
  if (Call_memory(k, r, ans)) return ans;
  if (r == 1) return D[k];
  if (k == 1) return prd[r];
  ans = (long long)(lyr[k] + 1) * Sd(r, core[k]) -
        (long long)lyr[k] * Sd(r / Div[k], core[k]);
  ans &= Sieve;
  Set_memory(k, r, ans);
  return ans;
}
int ANS;
int main() {
  scanf("%d%d%d", &A, &B, &C);
  code_id_in_block();
  code_out_of_block();
  initialize();
  ANS = 0;
  for (i = A * B; i; i--)
    if (cob[i]) {
      ANS += ((long long)uob[i] * Sd(C, i)) & Sieve;
      ANS &= Sieve;
      delete M[cob[i]];
      M[cob[i]] = NULL;
    }
  printf("%d\n", ANS);
}

### Prompt

Please formulate a cpp solution to the following problem:

Let's denote d(n) as the number of divisors of a positive integer n. You are given three integers a, b and c. Your task is to calculate the following sum:

<image>

Find the sum modulo 1073741824 (230).

Input

The first line contains three space-separated integers a, b and c (1 ≤ a, b, c ≤ 2000).

Output

Print a single integer — the required sum modulo 1073741824 (230).

Examples

Input

2 2 2


Output

20


Input

4 4 4


Output

328


Input

10 10 10


Output

11536

Note

For the first example.

  * d(1·1·1) = d(1) = 1; 
  * d(1·1·2) = d(2) = 2; 
  * d(1·2·1) = d(2) = 2; 
  * d(1·2·2) = d(4) = 3; 
  * d(2·1·1) = d(2) = 2; 
  * d(2·1·2) = d(4) = 3; 
  * d(2·2·1) = d(4) = 3; 
  * d(2·2·2) = d(8) = 4. 



So the result is 1 + 2 + 2 + 3 + 2 + 3 + 3 + 4 = 20.

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
int A, B, C;
const int Sieve = 0x3FFFFFFF;
int rid[2010], r0;
struct Memoblock {
  int V[150];
  void clear() {
    int i;
    for (i = 1; i <= r0; i++) V[i] = -1;
  }
};
void code_id_in_block() {
  int i;
  r0 = 0;
  for (i = 1; i <= C; i++) rid[i] = 0;
  for (i = 1; i <= C; i++)
    if (rid[C / i] == 0) rid[C / i] = ++r0;
}
int cob[4000002], uob[4000002], bs0;
void code_out_of_block() {
  int i, j, F = A * B;
  for (i = 1; i <= F; i++) cob[i] = uob[i] = 0;
  bs0 = 0;
  for (i = 1; i <= A; i++)
    for (j = 1; j <= B; j++) {
      uob[i * j]++;
      if (cob[i * j] == 0) cob[i * j] = ++bs0;
    }
}
Memoblock* M[2000001];
int P[2000010], Div[4000010], lyr[4000010], core[4000010];
int D[4000010], prd[2010];
void Eusieve(int N) {
  int i, j;
  Div[1] = lyr[1] = P[0] = 0;
  for (i = 2; i <= N; i++) Div[i] = i;
  for (i = 2; i <= N; i++) {
    if (Div[i] == i) {
      lyr[i] = core[i] = 1;
      P[++P[0]] = i;
    }
    for (j = 1; j <= P[0]; j++) {
      if (i * P[j] > N) break;
      Div[i * P[j]] = P[j];
      if (i % P[j] == 0) {
        lyr[i * P[j]] = lyr[i] + 1;
        core[i * P[j]] = core[i];
        break;
      } else {
        lyr[i * P[j]] = 1;
        core[i * P[j]] = i;
      }
    }
  }
  D[1] = 1;
  for (i = 2; i <= N; i++) D[i] = (lyr[i] + 1) * D[core[i]];
  prd[0] = 0;
  for (i = 1; i <= C; i++) prd[i] = prd[i - 1] + D[i];
}
void initialize() {
  int i;
  for (i = 1; i <= bs0; i++) M[i] = NULL;
  Eusieve(max(A * B, C));
}
bool Call_memory(int a, int b, int& r) {
  if (M[cob[a]] == NULL) return false;
  r = M[cob[a]]->V[rid[b]];
  return (r >= 0);
}
void Set_memory(int a, int b, int r) {
  if (M[cob[a]] == NULL) {
    M[cob[a]] = new Memoblock;
    M[cob[a]]->clear();
  }
  M[cob[a]]->V[rid[b]] = r;
}
int i;
int Sd(int r, int k) {
  int ans;
  if (r == 0) return 0;
  if (Call_memory(k, r, ans)) return ans;
  if (r == 1) return D[k];
  if (k == 1) return prd[r];
  ans = (long long)(lyr[k] + 1) * Sd(r, core[k]) -
        (long long)lyr[k] * Sd(r / Div[k], core[k]);
  ans &= Sieve;
  Set_memory(k, r, ans);
  return ans;
}
int ANS;
int main() {
  scanf("%d%d%d", &A, &B, &C);
  code_id_in_block();
  code_out_of_block();
  initialize();
  ANS = 0;
  for (i = A * B; i; i--)
    if (cob[i]) {
      ANS += ((long long)uob[i] * Sd(C, i)) & Sieve;
      ANS &= Sieve;
      delete M[cob[i]];
      M[cob[i]] = NULL;
    }
  printf("%d\n", ANS);
}

```