#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1000000007;
int main() {
  ios_base::sync_with_stdio(0);
  long long n, m;
  cin >> n >> m;
  vector<long long> x(2);
  x[0] = n / 2 + 1;
  x[1] = n + 1 - x[0];
  vector<long long> y(2);
  y[0] = m / 2 + 1;
  y[1] = m + 1 - y[0];
  vector<long long> rozX(n + 1, 0);
  vector<long long> rozY(m + 1, 0);
  for (int i = 0; i <= n; ++i)
    for (int j = 0; j <= i; ++j) ++rozX[i - j];
  for (int i = 0; i <= m; ++i)
    for (int j = 0; j <= i; ++j) ++rozY[i - j];
  long long odp = 0;
  for (int a = 0; a < 2; ++a) {
    for (int b = 0; b < 2; ++b) {
      for (int c = 0; c < 2; ++c) {
        for (int d = 0; d < 2; ++d) {
          for (int e = 0; e < 2; ++e) {
            for (int f = 0; f < 2; ++f) {
              long long l = (c - a) * (f - b);
              long long p = (d - b) * (e - a);
              long long r = l - p;
              if (r < 0) r *= -1;
              if (r % 2 == 0) {
                long long t = x[c] * x[a] % MOD * y[f] % MOD * y[b] % MOD *
                              y[d] % MOD * x[e] % MOD;
                odp = (odp + t) % MOD;
              }
            }
          }
        }
      }
    }
  }
  vector<vector<int> > nwd(n + 1, vector<int>(m + 1));
  for (int i = 0; i <= m; ++i) nwd[0][i] = i;
  for (int i = 1; i <= n; ++i) {
    nwd[i][0] = i;
    for (int j = 1; j <= m; ++j) {
      if (i <= j)
        nwd[i][j] = nwd[i][j % i];
      else
        nwd[i][j] = nwd[i % j][j];
    }
  }
  for (int i = 0; i <= n; ++i) {
    for (int j = 0; j <= m; ++j) {
      long long sr = nwd[i][j] - 1;
      if (sr <= 0) continue;
      long long x = rozX[i];
      long long y = rozY[j];
      long long t =
          x * y % MOD * sr % MOD * ((i == 0 || j == 0) ? 6 : 12) % MOD;
      odp -= t;
      if (odp < 0) odp += MOD;
    }
  }
  long long a = (n + 1) * (m + 1);
  long long c = a * (a - 1) * 3 % MOD;
  odp -= c;
  if (odp < 0) odp += MOD;
  odp -= a;
  if (odp < 0) odp += MOD;
  cout << odp;
  return 0;
}

### Prompt

Your task is to create a cpp solution to the following problem:

The Little Elephant is playing with the Cartesian coordinates' system. Most of all he likes playing with integer points. The Little Elephant defines an integer point as a pair of integers (x; y), such that 0 ≤ x ≤ w and 0 ≤ y ≤ h. Thus, the Little Elephant knows only (w + 1)·(h + 1) distinct integer points.

The Little Elephant wants to paint a triangle with vertexes at integer points, the triangle's area must be a positive integer. For that, he needs to find the number of groups of three points that form such triangle. At that, the order of points in a group matters, that is, the group of three points (0;0), (0;2), (2;2) isn't equal to the group (0;2), (0;0), (2;2).

Help the Little Elephant to find the number of groups of three integer points that form a nondegenerate triangle with integer area.

Input

A single line contains two integers w and h (1 ≤ w, h ≤ 4000).

Output

In a single output line print an integer — the remainder of dividing the answer to the problem by 1000000007 (109 + 7).

Examples

Input

2 1


Output

36


Input

2 2


Output

240

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1000000007;
int main() {
  ios_base::sync_with_stdio(0);
  long long n, m;
  cin >> n >> m;
  vector<long long> x(2);
  x[0] = n / 2 + 1;
  x[1] = n + 1 - x[0];
  vector<long long> y(2);
  y[0] = m / 2 + 1;
  y[1] = m + 1 - y[0];
  vector<long long> rozX(n + 1, 0);
  vector<long long> rozY(m + 1, 0);
  for (int i = 0; i <= n; ++i)
    for (int j = 0; j <= i; ++j) ++rozX[i - j];
  for (int i = 0; i <= m; ++i)
    for (int j = 0; j <= i; ++j) ++rozY[i - j];
  long long odp = 0;
  for (int a = 0; a < 2; ++a) {
    for (int b = 0; b < 2; ++b) {
      for (int c = 0; c < 2; ++c) {
        for (int d = 0; d < 2; ++d) {
          for (int e = 0; e < 2; ++e) {
            for (int f = 0; f < 2; ++f) {
              long long l = (c - a) * (f - b);
              long long p = (d - b) * (e - a);
              long long r = l - p;
              if (r < 0) r *= -1;
              if (r % 2 == 0) {
                long long t = x[c] * x[a] % MOD * y[f] % MOD * y[b] % MOD *
                              y[d] % MOD * x[e] % MOD;
                odp = (odp + t) % MOD;
              }
            }
          }
        }
      }
    }
  }
  vector<vector<int> > nwd(n + 1, vector<int>(m + 1));
  for (int i = 0; i <= m; ++i) nwd[0][i] = i;
  for (int i = 1; i <= n; ++i) {
    nwd[i][0] = i;
    for (int j = 1; j <= m; ++j) {
      if (i <= j)
        nwd[i][j] = nwd[i][j % i];
      else
        nwd[i][j] = nwd[i % j][j];
    }
  }
  for (int i = 0; i <= n; ++i) {
    for (int j = 0; j <= m; ++j) {
      long long sr = nwd[i][j] - 1;
      if (sr <= 0) continue;
      long long x = rozX[i];
      long long y = rozY[j];
      long long t =
          x * y % MOD * sr % MOD * ((i == 0 || j == 0) ? 6 : 12) % MOD;
      odp -= t;
      if (odp < 0) odp += MOD;
    }
  }
  long long a = (n + 1) * (m + 1);
  long long c = a * (a - 1) * 3 % MOD;
  odp -= c;
  if (odp < 0) odp += MOD;
  odp -= a;
  if (odp < 0) odp += MOD;
  cout << odp;
  return 0;
}

```