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>
const int mod = 1000000007;
int gcd(int a, int b) {
  while (b) a %= b, std::swap(a, b);
  return a;
}
int w, h;
int gc[4020][4020];
int co[4020][4020];
int main() {
  scanf("%d %d", &w, &h);
  long long n = (w + 1) * (h + 1);
  long long tot = (((n * (n - 1)) % mod) * (n - 2)) % mod;
  long long cl = clock();
  for (int i = 1; i < 4010; ++i) {
    for (int j = 1; j < 4010; ++j) {
      if (i > j) {
        gc[i][j] = gc[j][i];
      } else {
        gc[i][j] = gcd(j, i);
      }
    }
  }
  memset(co, 0, sizeof(co));
  for (int i = 1; i < 4010; ++i) {
    for (int j = 1; j < 4010; ++j) {
      co[i][j] = gc[i][j] - 1 + co[i][j - 1] + co[i - 1][j] - co[i - 1][j - 1];
    }
  }
  for (int i = 0; i <= w; ++i) {
    for (int j = 0; j <= h; ++j) {
      long long li;
      li = co[i][j];
      li += co[w - i][j];
      li += (j) * (j - 1) / 2;
      li += (i) * (i - 1) / 2;
      if (li >= mod) {
        li %= mod;
      }
      tot = tot - 6LL * li;
      while (tot < 0) {
        tot += mod;
      }
      if (tot >= mod) {
        tot %= mod;
      }
      long long evi = i / 2 + (w - i) / 2;
      long long oddi = w - evi;
      long long evj = j / 2;
      long long oddj = j - evj;
      ++evi;
      long long oddf = 0;
      long long p;
      long long q;
      p = oddi * oddj;
      if (p >= mod) {
        p %= mod;
      }
      q = oddi * evj;
      if (q >= mod) {
        q %= mod;
      }
      oddf += p * q;
      q = oddj * evi;
      if (q >= mod) {
        q %= mod;
      }
      oddf += p * q;
      q = evj * evi;
      if (q >= mod) {
        q %= mod;
      }
      oddf += p * q;
      oddf *= 6;
      if (oddf >= mod) {
        oddf %= mod;
      }
      tot -= oddf;
      if (tot < 0) {
        tot += mod;
      }
      oddi = i - i / 2;
      p = oddi * oddj;
      if (p >= mod) {
        p %= mod;
      }
      q = p * 6LL * (w + 1);
      if (q >= mod) {
        q %= mod;
      }
      tot -= q;
      if (tot < 0) {
        tot += mod;
      }
      tot %= mod;
    }
  }
  printf("%lld\n", tot);
  return 0;
}