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;
using System.Linq;


namespace Paiza
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] hw = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
            if (hw[0] * hw[1] % 3 == 0)
            {
                Console.WriteLine(0);
            }
            else Console.WriteLine(cutall(hw[0], hw[1]));
        }

        static long cutall(int H, int W)
        {
            //横，横に切る
            long SmaxSmin1 = H;
            SmaxSmin1 *= W;
            for (int cut1 = 1; cut1 <H; cut1++)
            {
                int cut2 = (H - cut1)/2;
                
                    long one = cut1;
                        one *= W;
                    long two = (cut2 - cut1);
                        two *= W;
                    long three = (H - cut2);
                    three *= W;
                    long Smax = Math.Max(one, Math.Max(two, three));
                    long Smin = Math.Min(one, Math.Min(two, three));
                    if (SmaxSmin1 > Smax - Smin) SmaxSmin1 = Smax - Smin;
                


            }

            //縦，縦に切る
            long SmaxSmin2 = H;
            SmaxSmin2 *= W;
            for (int cut1 = 1; cut1 <W; cut1++)
            {
                int cut2 = (W - cut1) / 2;
                {
                    long one = cut1;
                    one *= H;
                    long two = (cut2 - cut1);
                    two *= H;

                    long three = (W - cut2);
                    three *= H;
                    long Smax = Math.Max(one, Math.Max(two, three));
                    long Smin = Math.Min(one, Math.Min(two, three));
                    if (SmaxSmin2 > Smax - Smin) SmaxSmin2 = Smax - Smin;

                }
            }

            //横に切って下部分を縦にに切る
            long SmaxSmin3 = H;
            SmaxSmin3 *= W;

            for (int cut1 = 1; cut1 < H; cut1++)
            {
                int tatecut = W / 2;
                long one = cut1;
                 one *=W;
                long two = tatecut;
                two *=(H - cut1);

                long three = (W - tatecut);
                 three*= (H - cut1);
                    
                long Smax = Math.Max(one, Math.Max(two, three));
                long Smin = Math.Min(one, Math.Min(two, three));
                if (SmaxSmin3 > Smax - Smin) SmaxSmin3 = Smax - Smin;


            }

            //縦に切って右側を横にきる
            long SmaxSmin4 = H;
            SmaxSmin4 *= W;
            for (int cut1 = 1; cut1 < W ; cut1++)
            {
                int yokocut = H / 2;
                long one = cut1;
                 one *= H;
                long two = yokocut;
                two *= (W - cut1);
                long three = (H - yokocut);
                  three*= (W - cut1);
                long Smax = Math.Max(one, Math.Max(two, three));
                long Smin = Math.Min(one, Math.Min(two, three));
                if (SmaxSmin4 > Smax - Smin) SmaxSmin4 = Smax - Smin;
            }


            long output = Math.Min(Math.Min(SmaxSmin1, SmaxSmin2), Math.Min(SmaxSmin3, SmaxSmin4));
            return output;
        }
        

    }
}