#include <bits/stdc++.h>
using namespace std;
const int MAX = 10000;
const long long MOD = 1000000007;
int N, M;
int go[2][2][2];
int gcd(int a, int b) {
  if (a == 0) return b;
  return gcd(b % a, a);
}
long long bad() {
  long long res = 0;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < M; j++) {
      if (i == 0 && j == 0) continue;
      res += (1 + (i > 0 and j > 0)) * (gcd(i, j) - 1) * (long long)(N - i) *
             (long long)(M - j);
    }
  }
  res = res * 3 + (long long)N * M * (N * M - 1);
  res %= MOD;
  return res;
}
int cou(int a, int b) {
  if (b <= a) return 0;
  return (b - a - 1) / 2 + 1;
}
int main() {
  cin >> N >> M;
  N++;
  M++;
  long long res = -bad();
  for (int parx = 0; parx < 2; parx++) {
    for (int pary = 0; pary < 2; pary++) {
      for (int targ = 0; targ < 2; targ++) {
        long long add = 0;
        if (parx == 0) {
          if (pary == 0) {
            add = N * M;
          } else {
            add = N * cou(targ, M);
          }
        }
        if (parx == 1) {
          if (pary == 0) {
            add = M * cou(targ, N);
          } else {
            add = (N * M + (targ == 0)) / 2;
          }
        }
        go[parx][pary][targ] = add % MOD;
      }
    }
  }
  for (int a = 0; a < 2; a++) {
    for (int b = 0; b < 2; b++) {
      for (int i = a; i < N; i++) {
        for (int j = b; j < M; j++) {
          if (i == a and j == b) continue;
          int parx = (j - b) % 2, pary = (i - a) % 2;
          int targ = (j * a + i * b) % 2;
          res = (res + (long long)(cou(i, N) * cou(j, M) *
                                   (1 + (i != a and j != b))) *
                           go[parx][pary][targ]) %
                MOD;
        }
      }
    }
  }
  cout << (res * 2) % MOD << endl;
}

### Prompt

Please provide a Cpp coded solution to the problem described below:

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 int MAX = 10000;
const long long MOD = 1000000007;
int N, M;
int go[2][2][2];
int gcd(int a, int b) {
  if (a == 0) return b;
  return gcd(b % a, a);
}
long long bad() {
  long long res = 0;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < M; j++) {
      if (i == 0 && j == 0) continue;
      res += (1 + (i > 0 and j > 0)) * (gcd(i, j) - 1) * (long long)(N - i) *
             (long long)(M - j);
    }
  }
  res = res * 3 + (long long)N * M * (N * M - 1);
  res %= MOD;
  return res;
}
int cou(int a, int b) {
  if (b <= a) return 0;
  return (b - a - 1) / 2 + 1;
}
int main() {
  cin >> N >> M;
  N++;
  M++;
  long long res = -bad();
  for (int parx = 0; parx < 2; parx++) {
    for (int pary = 0; pary < 2; pary++) {
      for (int targ = 0; targ < 2; targ++) {
        long long add = 0;
        if (parx == 0) {
          if (pary == 0) {
            add = N * M;
          } else {
            add = N * cou(targ, M);
          }
        }
        if (parx == 1) {
          if (pary == 0) {
            add = M * cou(targ, N);
          } else {
            add = (N * M + (targ == 0)) / 2;
          }
        }
        go[parx][pary][targ] = add % MOD;
      }
    }
  }
  for (int a = 0; a < 2; a++) {
    for (int b = 0; b < 2; b++) {
      for (int i = a; i < N; i++) {
        for (int j = b; j < M; j++) {
          if (i == a and j == b) continue;
          int parx = (j - b) % 2, pary = (i - a) % 2;
          int targ = (j * a + i * b) % 2;
          res = (res + (long long)(cou(i, N) * cou(j, M) *
                                   (1 + (i != a and j != b))) *
                           go[parx][pary][targ]) %
                MOD;
        }
      }
    }
  }
  cout << (res * 2) % MOD << endl;
}

```