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

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
int mod = 1000000007;
int g[4010][4010];
int b[6];
int cnt[2][2];
int how[2][2];
int inv = 166666668;
int getC(int x, int y, int k) {
  if (k > cnt[x][y]) return 0;
  if (k == 0) return 1;
  if (k == 1) return cnt[x][y];
  if (k == 2) return ((cnt[x][y] * 1ll * (cnt[x][y] - 1)) / 2) % mod;
  long long res = cnt[x][y] * 1ll * (cnt[x][y] - 1) % mod;
  res = (res * (cnt[x][y] - 2)) % mod;
  res = (res * inv) % mod;
  return res;
}
int binstep(int a, int b) {
  if (b == 0) return 1;
  int v = binstep(a, b / 2);
  long long res = v * 1ll * v;
  res %= mod;
  if (b & 1) {
    res *= a;
    res %= mod;
  }
  return res;
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  long long res = 0;
  for (int i = (0); i < (n + 1); ++i)
    for (int j = (0); j < (m + 1); ++j) cnt[i & 1][j & 1]++;
  for (int i = (0); i < (1 << 6); ++i) {
    for (int j = (0); j < (6); ++j) b[j] = ((i >> j) & 1);
    int val1 = b[2] - b[0];
    if (val1 < 0) val1 = 1;
    int val2 = b[3] - b[1];
    if (val2 < 0) val2 = 1;
    int val3 = b[4] - b[0];
    if (val3 < 0) val3 = 1;
    int val4 = b[5] - b[1];
    if (val4 < 0) val4 = 1;
    int num1 = b[0] * 2 + b[1];
    int num2 = b[2] * 2 + b[3];
    int num3 = b[4] * 2 + b[5];
    if ((num2 < num1) || (num3 < num2)) continue;
    int val5 = val4 * val1 - val2 * val3;
    if (val5 == 0) {
      memset(how, 0, sizeof(how));
      how[b[0]][b[1]]++;
      how[b[2]][b[3]]++;
      how[b[4]][b[5]]++;
      long long cur = 1;
      for (int x = (0); x < (2); ++x)
        for (int y = (0); y < (2); ++y) {
          cur *= getC(x, y, how[x][y]);
          cur %= mod;
        }
      cur *= 6;
      cur %= mod;
      res += cur;
      res %= mod;
    }
  }
  for (int i = (0); i < (n + 1); ++i)
    for (int j = (0); j < (m + 1); ++j)
      if (i == 0)
        g[i][j] = j;
      else if (j == 0)
        g[i][j] = i;
      else if (i <= j)
        g[i][j] = g[i][j - i];
      else
        g[i][j] = g[i - j][j];
  for (int dx = (0); dx < (n + 1); ++dx)
    for (int dy = (-m); dy < (m + 1); ++dy) {
      if ((dx == 0) && (dy <= 0)) continue;
      long long mul =
          (n - dx + 1) * 1ll * (m - ((dy > 0) ? dy : -(dy)) + 1) % mod;
      int v = g[dx][((dy > 0) ? dy : -(dy))];
      v--;
      mul *= v;
      mul %= mod;
      mul *= 6;
      mul %= mod;
      res -= mul;
      if (res < 0) res += mod;
    }
  cout << res << endl;
  return 0;
}