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;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
 
class Program
{
    static void Main()
    {
        string[] inputs = Console.ReadLine().Split(' ');
        long H = long.Parse(inputs[0]);
        long W = long.Parse(inputs[1]);
        long result = 0;
        if(!(H % 3 == 0 || W % 3 == 0))
        {
            if(H > W)
            {
                long tmp = H;
                H = W;
                W = tmp;
            }
            long separatePoint = W / 2;
            long[] areas = new long[3];
            long areaGap = long.MaxValue;
            int i = 1;
            while (separatePoint > 0)
            {
                areas[0] = H * separatePoint;
                long H2 = H / 2, W2 = W - separatePoint;
                areas[1] = H2 * W2;
                areas[2] = (H - H2) * W2;
                Console.Error.WriteLine("1-{6} - H1: {0}, W1: {1}, H2: {2}, W2: {3}, H3: {4}, W3: {5}", H, separatePoint, H2, W2, H - H2, W2, i++);
                long compareAreaGap = areas.Max() - areas.Min();
                Console.Error.WriteLine("area1: {0}, area2: {1}, area3: {2}, gap: {3}", areas[0], areas[1], areas[2], compareAreaGap);
                if(areaGap > compareAreaGap)
                {
                    areaGap = compareAreaGap;
                    separatePoint--;
                    continue;
                }
                else break;
            }
            long tmp2 = H;
            H = W;
            W = tmp2;
            separatePoint = W / 2;
            long areaGap2 = long.MaxValue;
            i = 1;
            while (separatePoint > 0)
            {
                areas[0] = H * separatePoint;
                long H2 = H / 2, W2 = W - separatePoint;
                areas[1] = H2 * W2;
                areas[2] = (H - H2) * W2;
                Console.Error.WriteLine("2-{6} - H1: {0}, W1: {1}, H2: {2}, W2: {3}, H3: {4}, W3: {5}", H, separatePoint, H2, W2, H - H2, W2, i++);
                long compareAreaGap = areas.Max() - areas.Min();
                Console.Error.WriteLine("area1: {0}, area2: {1}, area3: {2}, gap: {3}", areas[0], areas[1], areas[2], compareAreaGap);
                if(areaGap2 > compareAreaGap)
                {
                    areaGap2 = compareAreaGap;
                    separatePoint--;
                    continue;
                }
                else break;
            }
            result = Math.Min(areaGap, areaGap2);
            result = result > Math.Min(H, W) ? Math.Min(H, W) : result;
        }
        Console.WriteLine(result);
    }
}