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;
const int inf = ~0U >> 1;
const long long INF = ~0ULL >> 1;
template <class T>
inline void read(T &n) {
  char c;
  for (c = getchar(); !(c >= '0' && c <= '9'); c = getchar())
    ;
  n = c - '0';
  for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0';
}
int Pow(int base, int n, int mo) {
  if (n == 0) return 1;
  if (n == 1) return base % mo;
  int tmp = Pow(base, n >> 1, mo);
  tmp = (long long)tmp * tmp % mo;
  if (n & 1) tmp = (long long)tmp * base % mo;
  return tmp;
}
const int mo = 1000000007;
long long C(int N) {
  if (N < 3) return 0;
  return (long long)N * (N - 1) % mo * (N - 2) % mo * Pow(6, mo - 2, mo) % mo;
}
long long gcd(long long x, long long y) {
  for (long long r = x % y; r; r = x % y) x = y, y = r;
  return y;
}
int w, h, cntx[2], cnty[2];
long long ans, Cnt[2][2];
int main() {
  scanf("%d%d", &w, &h);
  for (int i = (0); i <= (w); ++i) cntx[i % 2]++;
  for (int i = (0); i <= (h); ++i) cnty[i % 2]++;
  for (int cx = (0); cx <= (1); ++cx)
    for (int cy = (0); cy <= (1); ++cy) {
      for (int ax = (0); ax <= (1); ++ax)
        for (int ay = (0); ay <= (1); ++ay)
          for (int bx = (0); bx <= (1); ++bx)
            for (int by = (0); by <= (1); ++by)
              if ((cx * (ay - by) + cy * (bx - ax) + ax * by - bx * ay) % 2 ==
                  0)
                Cnt[cx][cy] +=
                    (long long)cntx[ax] * cntx[bx] * cnty[ay] * cnty[by];
      Cnt[cx][cy] %= mo;
    }
  for (int cx = (0); cx <= (w); ++cx)
    for (int cy = (0); cy <= (h); ++cy) ans += Cnt[cx % 2][cy % 2];
  ans %= mo;
  long long tmp = 0;
  tmp += (long long)(w + 1) * C(h + 1);
  tmp += (long long)(h + 1) * C(w + 1);
  tmp %= mo;
  for (int i = (1); i <= (w); ++i)
    for (int j = (1); j <= (h); ++j)
      tmp += (long long)(gcd(i, j) - 1) * 2 * (w - i + 1) * (h - j + 1),
          tmp %= mo;
  tmp = tmp * 6 % mo;
  ans -= tmp;
  int n = (w + 1) * (h + 1);
  tmp = (long long)n * n % mo * n % mo - C(n) * 6;
  ans -= tmp;
  ans = (ans % mo + mo) % mo;
  printf("%lld\n", ans);
  return 0;
}