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 Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

class Main {
	public static void main(String args[]) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		Solver solver = new Solver();
		solver.init();
		solver.readHead(in.readLine());
		// for (; solver.hasNext();) {
		// solver.readBody(in.readLine());
		// }
		// solver.solve();
	}
}

class Solver {
	int N;
	int H;
	int W;
	int cnt;

	public void init() {
		N = 0;
		cnt = 0;
	}

	public void readHead(String str) {
		String[] strArr = str.split(" ");
		// N = Integer.parseInt(strArr[0]);
		// System.out.println(N);

		H = Integer.parseInt(strArr[0]);
		W = Integer.parseInt(strArr[1]);

		if (H % 3 == 0) {
			System.out.println("0");
			return;
		}
		if (W % 3 == 0) {
			System.out.println("0");
			return;
		}

		long l;
		long m;
		if (H > W) {
			l = (long) H;
			m = (long) W;
		} else {
			l = (long) W;
			m = (long) H;
		}

		long l1;
		long m1;
		long l2;
		long m2;
		long l3;
		long m3;
		long min = Long.MAX_VALUE;

		// 長辺3分割
		l1 = l / 3;
		m1 = m;
		l2 = (l - l1) / 2;
		m2 = m;
		l3 = l - l1 - l2;
		m3 = m;
		if (l1 > 0 && m1 > 0 && l2 > 0 && m2 > 0 && l3 > 0 && m3 > 0)
			min = Long.min(min, diffMaxMin(l1 * m1, l2 * m2, l3 * m3));

		// 長辺２分割(切り捨て)
		l1 = l / 3;
		m1 = m;
		l2 = l - l1;
		m2 = m / 2;
		l3 = l - l1;
		m3 = m - m2;
		if (l1 > 0 && m1 > 0 && l2 > 0 && m2 > 0 && l3 > 0 && m3 > 0)
			min = Long.min(min, diffMaxMin(l1 * m1, l2 * m2, l3 * m3));

		// 長辺２分割(切り上げ)
		l1 = l / 3 + 1;
		m1 = m;
		l2 = l - l1;
		m2 = m / 2;
		l3 = l - l1;
		m3 = m - m2;
		if (l1 > 0 && m1 > 0 && l2 > 0 && m2 > 0 && l3 > 0 && m3 > 0)
			min = Long.min(min, diffMaxMin(l1 * m1, l2 * m2, l3 * m3));

		System.out.println(min);

	}

	private long diffMaxMin(long s1, long s2, long s3) {
		long min = s1;
		long max = s1;
		if (min > s2)
			min = s2;
		if (max < s2)
			max = s2;
		if (min > s3)
			min = s3;
		if (max < s3)
			max = s3;
		return max - min;
	}

	public boolean hasNext() {
		return cnt < N;
	}

	public void readBody(String str) {
		// System.out.println(str);
		cnt++;
	}

	public void solve() {
	}
}