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 Rust (1.15.1) (judge verdict: Accepted)

use std::cmp::{max, min};
use std::io::{stdin, Read};

macro_rules! parse {
    ($it: ident) => {
        $it.next().unwrap().parse().unwrap()
    };
    ($it: ident,2) => {
        (parse!($it), parse!($it))
    };
    ($it: ident,3) => {
        (parse!($it), parse!($it), parse!($it))
    };
    ($it: ident,4) => {
        (parse!($it), parse!($it), parse!($it), parse!($it))
    };
    ($it: ident, $n: ident) => {
        (&mut $it).take($n).map(|e| e.parse().unwrap()).collect();
    };
}

fn main() {
    let mut s = String::new();
    stdin().read_to_string(&mut s).unwrap();
    let mut it = s.split_whitespace();
    let (h, w): (i64, i64) = parse!(it, 2);
    let diff = |x: i64, y: i64, z: i64| {
        let r = max(x, max(y, z));
        let l = min(x, min(y, z));
        r - l
    };
    let mut ret = std::i64::MAX;

    // w / 3 or h / 3
    let mut parallel = |w, h| {
        let w0 = w / 3;
        let w1 = (w - w0) / 2;
        let w2 = w - w0 - w1;
        diff(h * w0, h * w1, h * w2)
    };
    ret = min(parallel(h, w), ret);
    ret = min(parallel(w, h), ret);
    // w/3, h/2
    let mut block = |w, h| {
        let h0 = h / 2;
        let h1 = h - h0;
        let mut ret = std::i64::MAX;
        for &d in &[-2, -1, 0, 1, 2] {
            let w0 = w / 3 + d;
            let w1 = w - w0;
            if w0 < 1 || w1 < 1 {
                continue;
            }
            ret = min(diff(w0 * h, h0 * w1, h1 * w1), ret);
        }
        ret
    };
    ret = min(block(w, h), ret);
    ret = min(block(h, w), ret);
    println!("{}", ret);
}