Problem:
Score : 400 points

Problem Statement

There is a bar of chocolate with a height of H blocks and a width of W blocks.
Snuke is dividing this bar into exactly three pieces.
He can only cut the bar along borders of blocks, and the shape of each piece must be a rectangle.

Snuke is trying to divide the bar as evenly as possible.
More specifically, he is trying to minimize S_{max} - S_{min}, where S_{max} is the area (the number of blocks contained) of the largest piece, and S_{min} is the area of the smallest piece.
Find the minimum possible value of S_{max} - S_{min}.

Constraints

2 ≤ H, W ≤ 10^5

Input

Input is given from Standard Input in the following format:

H W

Output

Print the minimum possible value of S_{max} - S_{min}.

Sample Input 1

3 5

Sample Output 1

0

In the division below, S_{max} - S_{min} = 5 - 5 = 0.

Sample Input 2

4 5

Sample Output 2

2

In the division below, S_{max} - S_{min} = 8 - 6 = 2.

Sample Input 3

5 5

Sample Output 3

4

In the division below, S_{max} - S_{min} = 10 - 6 = 4.

Sample Input 4

100000 2

Sample Output 4

1

Sample Input 5

100000 100000

Sample Output 5

50000

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        Solver sol = new Solver();
        sol.Solve();
#if DEBUG
        Console.ReadLine();
#endif
    }
}

class Solver
{
    int H;
    int W;

    public void Solve()
    {
        long ans;
        if (H % 3 == 0 || W % 3 == 0)
        {
            ans = 0;
        }
        else
        {
            ChocolateBar cb1 = new ChocolateBar(H, W);
            long s1 = cb1.DeltaS;
            if (s1 == 0)
            {
                ans = 0;
            }
            else if (H == W)
            {
                ans = s1;
            }
            else
            {
                ChocolateBar cb2 = new ChocolateBar(W, H);
                ans = Math.Min(s1, cb2.DeltaS);
            }
        }

        Console.WriteLine(ans);
    }

    public Solver()
    {
        int[] hw = ReadIntArray();
        H = hw[0];
        W = hw[1];
    }

    static String ReadString() { return Console.ReadLine(); }
    static int ReadInt() { return int.Parse(Console.ReadLine()); }
    static long ReadLong() { return long.Parse(Console.ReadLine()); }
    static double ReadDouble() { return double.Parse(Console.ReadLine()); }
    static String[] ReadStringArray() { return Console.ReadLine().Split(' '); }
    static int[] ReadIntArray() { return Console.ReadLine().Split(' ').Select(e => int.Parse(e)).ToArray(); }
    static long[] ReadLongArray() { return Console.ReadLine().Split(' ').Select(e => long.Parse(e)).ToArray(); }
    static double[] ReadDoubleArray() { return Console.ReadLine().Split(' ').Select(e => double.Parse(e)).ToArray(); }
}

// 縦に分割するチョコレートバー.
class ChocolateBar
{
    long H;
    long W;
    // 縦に分割した場合のSmax-Smin.
    public long DeltaS
    {
        get
        {
            long ps = ParallelS;
            if (ps == 0)
            {
                return ps;
            }
            else
            {
                return Math.Min(ps, VerticalS);
            }
        }
    }
    // 垂直に分割したときのSmax-Smin.
    long VerticalS
    {
        get
        {
            long min = SplitVerticalWith(1);
            for (int w = 2; w < W; w++)
            {
                long cur = SplitVerticalWith(w);
                if (cur < min)
                {
                    min = cur;
                }
                else
                {
                    break;
                }
            }
            return min;
        }
    }
    // 3つを並行に分割したときのSmax-Smin.
    long ParallelS
    {
        get
        {
            if (W % 3 == 0)
            {
                return 0;
            }
            else
            {
                return H;
            }
        }
    }
    public ChocolateBar(int h, int w)
    {
        H = h;
        W = w;
    }

    // 1つ目をH*wとし、残りをそれと垂直に分割したときのSmax-Sminを返す.
    long SplitVerticalWith(int w)
    {
        long s1 = H * w;
        long s2 = (H / 2) * (W - w);
        long s3 = (H - H / 2) * (W - w);
        //Console.WriteLine("{0},{1}", w, Math.Max(s1, s3) - Math.Min(s1, s2));
        return Math.Max(s1, s3) - Math.Min(s1, s2);
    }
}