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;
use std::fmt::Debug;
use std::io;
use std::io::{Read, Stdin};
use std::str;
use std::str::FromStr;

fn main() {
    let mut sc = Scanner::new();
    let (h, w) = (sc.parse(), sc.parse());
    println!("{}", solve(h, w));
}


fn solve(h: usize, w: usize) -> usize {
    let min_s_diff1 = {
        match h % 3 {
            0 => 0,
            _ => w,
        }
    };
    let min_s_diff2 = {
        match w % 3 {
            0 => 0,
            _ => h,
        }
    };
    let min_s_diff3 = {
        let mut min_s_diff3 = h * w;
        for h1 in 1..h {
            let s1 = w * h1;
            let s2 = (h - h1) * (w / 2);
            let s3 = (h - h1) * (w / 2 + (w % 2));
            if s1 <= s2 {
                min_s_diff3 = cmp::min(min_s_diff3, s3 - s1)
            } else if s1 <= s3 {
                min_s_diff3 = cmp::min(min_s_diff3, s3 - s2)
            } else if s3 < s1 {
                min_s_diff3 = cmp::min(min_s_diff3, s1 - s2);
                break;
            }
        }
        min_s_diff3
    };
    let min_s_diff4 = {
        let mut min_s_diff4 = h * w;
        for w1 in 1..w {
            let s1 = w1 * h;
            let s2 = (w - w1) * (h / 2);
            let s3 = (w - w1) * (h / 2 + (h % 2));
            if s1 <= s2 {
                min_s_diff4 = cmp::min(min_s_diff4, s3 - s1)
            } else if s1 <= s3 {
                min_s_diff4 = cmp::min(min_s_diff4, s3 - s2)
            } else if s3 < s1 {
                min_s_diff4 = cmp::min(min_s_diff4, s1 - s2);
                break;
            }
        }
        min_s_diff4
    };
    *[min_s_diff1, min_s_diff2, min_s_diff3, min_s_diff4]
         .iter()
         .min()
         .unwrap()
}


struct Scanner {
    stdin: Stdin,
    buf: Vec<u8>,
}

impl Scanner {
    fn new() -> Scanner {
        Scanner {
            stdin: io::stdin(),
            buf: Vec::with_capacity(256),
        }
    }

    fn parse<T: FromStr>(&mut self) -> T
        where <T as FromStr>::Err: Debug
    {
        self.buf.clear();
        let mut it = self.stdin.lock().bytes();
        let mut c = it.next().unwrap().unwrap();
        while c == ' ' as u8 || c == '\n' as u8 {
            c = it.next().unwrap().unwrap();
        }
        while !(c == ' ' as u8 || c == '\n' as u8) {
            self.buf.push(c);
            c = it.next().unwrap().unwrap();
        }
        str::from_utf8(&self.buf).unwrap().parse::<T>().unwrap()
    }
}