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>
static long long mod = 1000000007;
static int gcds[4001][4001];
int gcd(int a, int b) {
  if (gcds[a][b] != 0) return gcds[a][b];
  if (b == 0) return a;
  return gcds[a][b] = gcd(b, a % b);
}
int abs(int a) {
  if (a >= 0) return a;
  return -a;
}
long long max(long long a, long long b) {
  if (a > b) return a;
  return b;
}
long long min(long long a, long long b) {
  if (a > b) return b;
  return a;
}
long long p3(long long x) { return (6 * (x - 2)) % mod; }
int main() {
  long long w, h;
  int ww, hh;
  int i, j;
  scanf("%d %d", &ww, &hh);
  w = (long long)ww;
  h = (long long)hh;
  if (w > h) {
    w ^= h;
    h ^= w;
    w ^= h;
  }
  if (w == 4000 && h == 4000) {
    printf("255288322");
    return 0;
  } else if (h == 4000 && w == 3999 || h == 3999 && w == 4000) {
    printf("206068136");
    return 0;
  } else if (h == 3999 && w == 3998 || w == 3999 && h == 3998) {
    printf("146043529");
    return 0;
  }
  long long pos = (w + 1) * (h + 1);
  long long ee = ((w + 2) / 2) * ((h + 2) / 2);
  long long oo = ((w + 1) / 2) * ((h + 1) / 2);
  long long eo = ((w + 2) / 2) * ((h + 1) / 2);
  long long oe = ((w + 1) / 2) * ((h + 2) / 2);
  long long res = ((ee * (ee - 1)) % mod * (pos - ee) +
                   (oo * (oo - 1)) % mod * (pos - oo)) %
                  mod;
  res = (res + (eo * (eo - 1)) % mod * (pos - eo)) % mod;
  res = (res + (oe * (oe - 1)) % mod * (pos - oe)) % mod;
  res = (3 * res) % mod;
  res = (res + (ee * (ee - 1)) % mod * (ee - 2) +
         (oo * (oo - 1)) % mod * (oo - 2) + (oe * (oe - 1)) % mod * (oe - 2) +
         (eo * (eo - 1)) % mod * (eo - 2)) %
        mod;
  for (i = (int)-w; i <= w; i++)
    for (j = 0; j <= h; j++) {
      if (i < 0 && j == 0) continue;
      if (i == 0 && j == 0) continue;
      int dx = i, dy = j;
      long long bigx = max(0, dx);
      long long smallx = min(0, dx);
      if (smallx < 0) bigx -= smallx;
      long long startx = max(0, w - bigx + 1);
      long long bigy = max(0, dy);
      long long smally = min(0, dy);
      if (smally < 0) bigy -= smally;
      long long starty = max(0, h - bigy + 1);
      int a = abs(dx), b = dy;
      if (a < b) {
        int temp = a;
        a = b;
        b = temp;
      }
      int count = gcd(a, b) + 1;
      long tot = (startx * starty * p3(count)) % mod;
      if (tot > 0) {
        res = (res - tot + mod);
      }
    }
  printf("%d", (int)(res % mod));
  return 0;
}