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 JAVA):

Solution:


import java.io.*;
import java.math.BigInteger;
import static java.math.BigInteger.*;


import java.util.*;

public class Solution{

    long mod=1000000007;
    void solve()throws Exception
    {
        int n=4001;
        int[][]gcd=new int[n+1][n+1];
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
            {
                if(i==0 || j==0)
                    gcd[i][j]=i+j;
                else if(i>=j)
                    gcd[i][j]=gcd[i-j][j];
                else
                    gcd[i][j]=gcd[i][j-i];
            }
        long res=0;
        int w=nextInt();
        int h=nextInt();
        for(int x1=0;x1<2;x1++)
            for(int x2=0;x2<2;x2++)
                for(int x3=0;x3<2;x3++)
                    for(int y1=0;y1<2;y1++)
                        for(int y2=0;y2<2;y2++)
                            for(int y3=0;y3<2;y3++)
                            {
                                int[]x=new int[]{x1,x2,x3};
                                int rem=Math.abs((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1));
                                if(rem%2!=0)
                                    continue;
                                long a=count(x,w);
                                long b=count(new int[]{y1,y2,y3},h);
                                res+=a*b;
                                res%=mod;
                            }

        long z=0;
        for(int dx=1;dx<=w;dx++)
            for(int dy=1;dy<=h;dy++)
            {
                long cnt=(w-dx+1)*(h-dy+1);
                long g=gcd[dx][dy];
                z=(z+(g)*cnt*6);
                z%=mod;
            }
        z*=2;
        z%=mod;

        z+=(w+1L)*(w+1)*(w+1)%mod*(h+1);
        z%=mod;

        z+=(h+1L)*(h+1)*(h+1)%mod*(w+1);
        z%=mod;

        res=(res-z)%mod;
        res+=mod;
        res%=mod;
        res+=(w+1)*(h+1);
        res%=mod;

        System.out.println(res);




    }



    private long count(int[] x, int w) {
        long res=1;
        long[]num=new long[2];
        num[0]=1+w/2;
        num[1]=w+1-num[0];
        for(int X: x)
        {
            res*=num[X];
            res%=mod;
        }
        return res;

    }
    ////////////
    BufferedReader reader;
    PrintWriter writer;
    StringTokenizer stk;
    void run()throws Exception
    {

        reader=new BufferedReader(new InputStreamReader(System.in));
        // reader=new BufferedReader(new FileReader("input.txt"));
        stk=null;
        writer=new PrintWriter(new PrintWriter(System.out));
        //writer=new PrintWriter(new FileWriter("output.txt"));
        solve();
        reader.close();
        writer.close();
    }
    int nextInt()throws Exception
    {
        return Integer.parseInt(nextToken());
    }

    long nextLong()throws Exception
    {
        return Long.parseLong(nextToken());

    }
    double nextDouble()throws Exception
    {
        return Double.parseDouble(nextToken());


    }

    String nextString()throws Exception
    {
        return nextToken();
    }
    String nextLine()throws Exception
    {
        return reader.readLine();
    }
    String nextToken()throws Exception
    {
        if(stk==null || !stk.hasMoreTokens())
        {
            stk=new StringTokenizer(nextLine());
            return nextToken();

        }
        return stk.nextToken();
    }

    public static void main(String[]args) throws Exception
    {
        new Solution().run();
    }








}