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.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using static System.Console;
using static System.Math;
class Simple {
    private int H, W;
    private string[] a;
    void Solve() {
        //input
        H = io.Int;
        W = io.Int;
        //cal
        var ans = long.MaxValue;
        //type A1 横横横
        if(H > 3)
            ans = Min(ans, A(H, W));
        //type A2 縦縦縦
        if(W > 3)
            ans = Min(ans, A(W, H));
        //type B1 縦横横
        ans = Min(ans, B(H, W));
        //rtpe B2 横縦縦
        ans = Min(ans, B(W, H));
        //ret
        WriteLine(ans);
    }
    long A(long a, long b) => a % 3 == 0 ? 0 : b;
    long B(long a, long b) {
        var ret = long.MaxValue;
        var aIsOdd = a % 2 != 0;
        for(int i = 1; i <= b - 1; ++i) {
            var v1 = a * i;
            var v2 = (b - i) * (a / 2);
            var v3 = a % 2 == 0 ? (b - i) * (a / 2) : (b - i) * (a / 2) + 1;
            ret = Min(ret, myMax(v1, v2, v3) - myMin(v1, v2, v3));
        }
        return ret;
    }
    long myMin(params long[] a) => a.Min();
    long myMax(params long[] a) => a.Max();
    SimpleIO io = new SimpleIO();
    public static void Main(string[] args) => new Simple().Stream();
    private void Stream() {
        //var exStdIn = new System.IO.StreamReader("stdin.txt");
        //SetIn(exStdIn);
        Solve();
        io.Flush();
    }
}
class SimpleIO {
    string[] _nextBuffer;
    int _bufferCnt;
    char[] cs = new char[] {' ', '"', ','};
    StreamWriter sw = new StreamWriter(OpenStandardOutput()) {
        AutoFlush = true
    };
    public SimpleIO() {
        _nextBuffer = new string[0];
        _bufferCnt = 0;
        SetOut(sw);
    }
    string Next() {
        if(_bufferCnt < _nextBuffer.Length)
            return _nextBuffer[_bufferCnt++];
        var st = ReadLine();
        while(st == "")
            st = ReadLine();
        if(st != null)
            _nextBuffer = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
        else
            st = "";
        _bufferCnt = 0;
        return _nextBuffer[_bufferCnt++];
    }
    public string String => Next();
    public char Char => char.Parse(String);
    public int Int => int.Parse(String);
    public long Long => long.Parse(String);
    public double Double => double.Parse(String);
    public void Flush() => Out.Flush();
}