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;
long long mod = 1000000007;
long long po(long long a, long long b) {
  vector<int> vec;
  for (;;) {
    if (b == 0) {
      break;
    }
    vec.push_back(b % 2);
    b /= 2;
  }
  reverse(vec.begin(), vec.end());
  long long ret = 1;
  for (int i = 0; i < vec.size(); i++) {
    ret *= ret;
    ret %= mod;
    if (vec[i]) {
      ret *= a;
      ret %= mod;
    }
  }
  return ret;
}
long long inv(long long a) { return po(a, mod - 2); }
long long kai[100001];
void calc() {
  kai[0] = 1;
  for (int i = 1; i <= 100000; i++) {
    kai[i] = kai[i - 1] * i;
    kai[i] %= mod;
  }
}
long long com2(long long a, long long b) {
  if (a < b) {
    return 0;
  }
  long long ret = kai[a];
  ret *= inv(kai[b]);
  ret %= mod;
  ret *= inv(kai[a - b]);
  ret %= mod;
  return ret;
}
long long com(long long a, long long b) {
  if (b == 2) {
    a = (a - 1) % mod + 1;
    return (a * (a - 1) / 2) % mod;
  } else {
    a = (a - 2) % mod + 2;
    long long ret = a;
    ret *= (a - 1);
    ret /= 2;
    ret %= mod;
    ret *= (a - 2);
    ret %= mod;
    ret *= inv(3);
    ret %= mod;
    return ret;
  }
}
long long dp[4003][4003];
long long gcd(long long a, long long b) {
  if (a > b) {
    swap(a, b);
  }
  for (;;) {
    b %= a;
    if (!b) {
      return a;
    }
    swap(a, b);
  }
}
int main() {
  int mx, my;
  scanf("%d%d", &mx, &my);
  mx++;
  my++;
  long long a, b, c, d;
  a = ((mx + 1) / 2) * ((my + 1) / 2);
  b = (mx / 2) * ((my + 1) / 2);
  c = ((mx + 1) / 2) * (my / 2);
  d = (mx / 2) * (my / 2);
  long long ret = 0;
  long long sum = a + b + c + d;
  ret += com(a, 3);
  ret += com(b, 3);
  ret += com(c, 3);
  ret += com(d, 3);
  ret += com(a, 2) * (sum - a);
  ret += com(b, 2) * (sum - b);
  ret += com(c, 2) * (sum - c);
  ret += com(d, 2) * (sum - d);
  ret %= mod;
  for (int i = 1; i < mx; i++) {
    for (int j = 1; j < my; j++) {
      dp[i + 1][j + 1] =
          (dp[i][j + 1] + dp[i + 1][j] - dp[i][j] + gcd(i, j) - 1) % mod;
      ret -= dp[i + 1][j + 1] + dp[i + 1][j + 1];
      ret = (ret + mod + mod) % mod;
    }
  }
  ret -= mx * com(my, 3);
  ret -= my * com(mx, 3);
  ret %= mod;
  if (ret < 0) {
    ret += mod;
  }
  ret *= 6;
  ret %= mod;
  printf("%I64d\n", ret);
}