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: Wrong Answer)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ABC062_ChocolateBar
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] input = Console.ReadLine().Split(' ').Select(elem => int.Parse(elem)).ToArray();
            int H = input[0];
            int W = input[1];

            Box boxParent = BoxFactory.CreateBox(H, W);
            long diff = long.MaxValue;

            List<Box> boxList = new List<Box>();
            for (int i = 1; i <= W - 1; i++)
            {
                Box[] children = boxParent.HorizonalSplit(i);

                boxList.Add(children[0]);

                // children[1]に対して再度実施
                {
                    for (int j = 1; j <= children[1].Width - 1; j++)
                    {
                        boxList.AddRange(children[1].HorizonalSplit(i));
                        diff = Math.Min(diff, boxList.Max(elem => elem.Area) - boxList.Min(elem => elem.Area));
                        boxList.RemoveRange(1, 2);
                    }

                    for (int j = 1; j <= children[1].Height - 1; j++)
                    {
                        boxList.AddRange(children[1].VerticalSplit(i));
                        diff = Math.Min(diff, boxList.Max(elem => elem.Area) - boxList.Min(elem => elem.Area));
                        boxList.RemoveRange(1, 2);
                    }
                }
            }

            boxList.Clear();
            for (int i = 1; i < H - 1; i++)
            {
                Box[] children = boxParent.VerticalSplit(i);

                boxList.Add(children[0]);

                // children[1]に対して再度実施
                for (int j = 1; j <= children[1].Width - 1; j++)
                {
                    boxList.AddRange(children[1].HorizonalSplit(i));
                    diff = Math.Min(diff, boxList.Max(elem => elem.Area) - boxList.Min(elem => elem.Area));
                    boxList.RemoveRange(1, 2);
                }

                for (int j = 1; j <= children[1].Height - 1; j++)
                {
                    boxList.AddRange(children[1].VerticalSplit(i));
                    diff = Math.Min(diff, boxList.Max(elem => elem.Area) - boxList.Min(elem => elem.Area));
                    boxList.RemoveRange(1, 2);
                }
            }

            // 出力
            Console.WriteLine(diff.ToString());
        }
    }

    public static class BoxFactory
    {
        private static Dictionary<string, Box> cache = new Dictionary<string, Box>();

        public static Box CreateBox(int height, int width)
        {
            string key = height.ToString() + "," + width.ToString();
            if (cache.ContainsKey(key))
            {
                return cache[key];
            }
            else
            {
                Box box = new Box(height, width);
                cache.Add(key, box);
                return box;
            }
        }
    }

    public class Box
    {
        public Box(int height, int width)
        {
            this.Height = height;
            this.Width = width;
            this.Area = height * width;
        }

        public int Height { get; set; }
        public int Width { get; set; }
        public long Area { get; set; }

        public Box[] HorizonalSplit(int x)
        {
            Box[] ret = new Box[2];
            ret[0] = BoxFactory.CreateBox(this.Height, x);
            ret[1] = BoxFactory.CreateBox(this.Height, this.Width - x);

            return ret;
        }

        public Box[] VerticalSplit(int y)
        {
            Box[] ret = new Box[2];
            ret[0] = BoxFactory.CreateBox(y, this.Width);
            ret[1] = BoxFactory.CreateBox(this.Height - y, this.Width);

            return ret;
        }
    }
}