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)

#[macro_use]
mod input {

use std;
use std::io;

const SPLIT_DELIMITER: char = ' ';

#[macro_export]
#[allow(unused_macros)]
macro_rules! input {
    ( $($x:expr ),*) => {
        {
            let temp_str = input_line_str();
            let mut split_result_iter = temp_str.split_whitespace();
                $(
                let buf_split_result = split_result_iter.next();
                let buf_split_result = buf_split_result.unwrap();
                    ($x) = buf_split_result.parse().unwrap();
                )*
        }
    };
}

#[allow(dead_code)]
pub fn input_line_str() -> String {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    s.trim().to_string()
}

#[allow(dead_code)]
pub fn p<T>(t: T)
where
    T: std::fmt::Display,
{
    println!("{}", t);
}

#[allow(dead_code)]
pub fn input_vector2d<T>(line: usize) -> Vec<Vec<T>>
where
    T: std::str::FromStr,
{
    let mut v: Vec<Vec<T>> = Vec::new();

    for _ in 0..line {
        let vec_line = input_vector();
        v.push(vec_line);
    }
    v
}

#[allow(dead_code)]
pub fn input_vector<T>() -> Vec<T>
where
    T: std::str::FromStr,
{
    let mut v: Vec<T> = Vec::new();

    let s = input_line_str();
    let split_result = s.split(SPLIT_DELIMITER);
    for z in split_result {
        let buf = match z.parse() {
            Ok(r) => r,
            Err(_) => panic!("Parse Error"),
        };
        v.push(buf);
    }
    v
}

#[allow(dead_code)]
pub fn str2vec(s: &str) -> Vec<char> {
    let mut v: Vec<char> = Vec::new();
    for c in s.chars() {
        v.push(c);
    }
    v
}

}

use input::*;
use std::cmp;

fn calc_h(h: usize, w: usize, a: usize) -> usize {
    let mut v1 = vec![a * w];
    let mut v2 = vec![a * w];
    if (h - a) / 2 == 0 {
        v1.push(usize::max_value());
    }
    v1.push((h - a) / 2 * w);
    if (h - a) % 2 != 0 {
        v1.push(((h - a) / 2 + 1) * w);
    }
    if (h - a) == 0 {
        v2.push(usize::max_value());
    }
    v2.push((w / 2) * (h - a));
    if w % 2 != 0 {
        v2.push(((w / 2) + 1) * (h - a));
    }
    let x = v1.iter().max().unwrap() - v1.iter().min().unwrap();
    let y = v2.iter().max().unwrap() - v2.iter().min().unwrap();
    cmp::min(x, y)
}

fn calc_w(h: usize, w: usize, a: usize) -> usize {
    let mut v1 = vec![a * h];
    let mut v2 = vec![a * h];
    if (w - a) / 2 == 0 {
        v1.push(usize::max_value());
    }
    v1.push((w - a) / 2 * h);
    if (w - a) % 2 != 0 {
        v1.push(((w - a) / 2 + 1) * h);
    }
    if (w - a) == 0 {
        v2.push(usize::max_value());
    }
    v2.push((h / 2) * (w - a));
    if h % 2 != 0 {
        v2.push(((h / 2) + 1) * (w - a));
    }
    let x = v1.iter().max().unwrap() - v1.iter().min().unwrap();
    let y = v2.iter().max().unwrap() - v2.iter().min().unwrap();
    cmp::min(x, y)
}

fn main() {
    let (h, w): (usize, usize);
    input!(h, w);
    let mut min = usize::max_value();
    for z in 1..h + 1 {
        min = cmp::min(calc_h(h, w, z), min);
    }
    for z in 1..w + 1 {
        min = cmp::min(calc_w(h, w, z), min);
    }
    p(min);
}