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 n, m;
long long as = 0;
int p[1000002], q[1000002], r[1000002], inv6;
int K;
int po(int a, int b) {
  int t = 1;
  for (; b; b >>= 1, a = 1LL * a * a % 1000000007)
    if (b & 1) t = 1LL * t * a % 1000000007;
  return t;
}
void bl() {
  long long ans = 0;
  for (int xa = 0; xa <= n; xa++)
    for (int ya = 0; ya <= m; ya++)
      for (int xb = xa; xb <= n; xb++)
        for (int yb = xb == xa ? ya + 1 : 0; yb <= m; yb++)
          for (int xc = xb; xc <= n; xc++)
            for (int yc = xc == xb ? yb + 1 : 0; yc <= m; yc++) {
              int S = (xb - xa) * (yc - ya) - (xc - xa) * (yb - ya);
              if (S % (K * 2) == 0 && S != 0) ++ans;
            }
  printf("%lld\n", ans);
}
void bl2() {
  long long ans = 0;
  for (int xa = 0; xa <= n; xa++)
    for (int ya = 0; ya <= m; ya++)
      for (int xb = 0; xb <= n; xb++)
        for (int yb = 0; yb <= m; yb++)
          for (int xc = 0; xc <= n; xc++)
            for (int yc = 0; yc <= m; yc++) {
              int S = (xb - xa) * (yc - ya) - (xc - xa) * (yb - ya);
              if (S % (2 * K) == 0) ++ans;
            }
  printf("%lld\n", ans);
}
int pr[1000002], is[1000002], mu[1000002], um[1000002], ium[1000002],
    ijum[1000002], tot;
void G() {
  n = 1e6;
  mu[1] = 1;
  for (int i = 2; i <= n; i++) {
    if (!is[i]) {
      pr[++tot] = i;
      mu[i] = -1;
    }
    for (int j = 1; j <= tot && i * pr[j] <= n; j++) {
      is[i * pr[j]] = 1;
      if (i % pr[j] == 0) {
        mu[i * pr[j]] = 0;
        break;
      } else
        mu[i * pr[j]] = -mu[i];
    }
  }
  for (int i = 1; i <= n; i++) um[i] = um[i - 1] + mu[i];
  for (int i = 1; i <= n; i++) ium[i] = (ium[i - 1] + mu[i] * i) % 1000000007;
  for (int i = 1; i <= n; i++)
    ijum[i] = (ijum[i - 1] + 1LL * mu[i] * i * i) % 1000000007;
}
int hp[1000002], hq[1000002];
int G1(int n, int m) {
  int u = 0;
  for (int i = 1, j; i <= min(n, m); i = j + 1) {
    j = min(n / (n / i), m / (m / i));
    u = (u + 1LL * (um[j] - um[i - 1]) * (n / i) % 1000000007 * (m / i)) %
        1000000007;
  }
  return u;
}
int G2(int n, int m) {
  int u = 0;
  for (int i = 1, j; i <= min(n, m); i = j + 1) {
    j = min(n / (n / i), m / (m / i));
    u = (u + 1LL * (ium[j] - ium[i - 1]) *
                 (1LL * (n / i) * (n / i + 1) / 2 % 1000000007) % 1000000007 *
                 (m / i)) %
        1000000007;
  }
  return u;
}
int G3(int n, int m) {
  int u = 0;
  for (int i = 1, j; i <= min(n, m); i = j + 1) {
    j = min(n / (n / i), m / (m / i));
    u = (u + 1LL * (ium[j] - ium[i - 1]) *
                 (1LL * (m / i) * (m / i + 1) / 2 % 1000000007) % 1000000007 *
                 (n / i)) %
        1000000007;
  }
  return u;
}
int G4(int n, int m) {
  int u = 0;
  for (int i = 1, j; i <= min(n, m); i = j + 1) {
    j = min(n / (n / i), m / (m / i));
    u = (u + 1LL * (ijum[j] - ijum[i - 1]) *
                 (1LL * (m / i) * (m / i + 1) / 2 % 1000000007) % 1000000007 *
                 (1LL * (n / i) * (n / i + 1) / 2 % 1000000007)) %
        1000000007;
  }
  return u;
}
int H(int x) {
  return 1LL * x * (x + 1) % 1000000007 * (2LL * x + 1) % 1000000007 * inv6 %
         1000000007;
}
int H2(int x) {
  return 1LL * (1LL * x * (x + 1) / 2 % 1000000007) *
         (1LL * x * (x + 1) / 2 % 1000000007) % 1000000007;
}
int main() {
  G();
  inv6 = po(6, 1000000007 - 2);
  cin >> n >> m;
  K = 1;
  K <<= 1;
  for (int i = 0; i <= min(n, K - 1); i++)
    for (int j = 0; j <= min(m, K - 1); j++) {
      int u = 0;
      for (int k = 0; k < K; k++)
        p[k] = floor(1. * (n - i - k) / K) - floor(1. * (-i - 1 - k) / K);
      for (int k = 0; k < K; k++)
        q[k] = floor(1. * (m - j - k) / K) - floor(1. * (-j - 1 - k) / K);
      for (int k = 0; k < K; k++)
        if (p[k] != hp[k]) {
          for (int l = 0, u = 0; l < K; l++, u = u + k + (u + k >= K ? -K : 0))
            r[u] =
                (r[u] - 1LL * hp[k] * hq[l] + 1LL * p[k] * hq[l]) % 1000000007;
        }
      for (int k = 0; k < K; k++) hp[k] = p[k];
      for (int l = 0; l < K; l++)
        if (q[l] != hq[l]) {
          for (int k = 0, u = 0; k < K; k++, u = u + l + (u + l >= K ? -K : 0))
            r[u] = (r[u] - 1LL * p[k] * hq[l] + 1LL * p[k] * q[l]) % 1000000007;
        }
      for (int k = 0; k < K; k++) hq[k] = q[k];
      for (int k = 0; k < K; k++) u = (u + 1LL * r[k] * r[k]) % 1000000007;
      as = (as +
            u * (1LL * (1 + (n - i) / K) * (1 + (m - j) / K) % 1000000007)) %
           1000000007;
    }
  K >>= 1;
  as = (as - 1LL * (n + 1) * (m + 1)) % 1000000007;
  int q1 = 0, q2 = 0, q3 = 0, q4 = 0;
  for (int i = 1, j; i <= min(n, m); i = j + 1) {
    j = min(n / (n / i), m / (m / i));
    q1 =
        (q1 + 1LL * (i + j) * (j - i + 1) / 2 % 1000000007 * G1(n / i, m / i)) %
        1000000007;
  }
  as = (as - 12LL * (n + 1) * (m + 1) % 1000000007 * q1) % 1000000007;
  for (int i = 1, j; i <= min(n, m); i = j + 1) {
    j = min(n / (n / i), m / (m / i));
    q2 = (q2 + 1LL * (H(j) - H(i - 1)) * G2(n / i, m / i)) % 1000000007;
  }
  for (int i = 1, j; i <= min(n, m); i = j + 1) {
    j = min(n / (n / i), m / (m / i));
    q3 = (q3 + 1LL * (H(j) - H(i - 1)) * G3(n / i, m / i)) % 1000000007;
  }
  for (int i = 1, j; i <= min(n, m); i = j + 1) {
    j = min(n / (n / i), m / (m / i));
    q4 = (q4 + 1LL * (H2(j) - H2(i - 1)) * G4(n / i, m / i)) % 1000000007;
  }
  as = (as + 12LL * (m + 1) % 1000000007 * q2 +
        12LL * (n + 1) % 1000000007 * q3 - 12LL * q4) %
       1000000007;
  as = (as - 6LL * (n + 1) * (m + 1) % 1000000007 *
                 (1LL * m * (m + 1) / 2 % 1000000007)) %
       1000000007;
  as = (as + 6LL * (n + 1) * H(m)) % 1000000007;
  as = (as - 6LL * (m + 1) * (n + 1) % 1000000007 *
                 (1LL * n * (n + 1) / 2 % 1000000007)) %
       1000000007;
  as = (as + 6LL * (m + 1) * H(n)) % 1000000007;
  cout << 1LL * (as + 1000000007) % 1000000007 << endl;
  return 0;
}