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++ (GCC 9.2.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
#define rep(i,n)    for(long long i = 0; i < (n) ; ++i)
#define orep(i,n)   for(long long i = 1; i <= (n); ++i)   // one rep
#define drep(i,n)   for(long long i = (n)-1; i >= 0; --i) // down rep
#define srep(i,s,t) for(long long i = (s); i < (t); ++i)  // set rep
#define rng(x)  (x).begin(),(x).end()

  // range
#define rrng(a) (a).rbegin(),(a).rend() // reverse range
#define isin(x,l,r) ((l) <= (x) && (x) < (r))
#define ru(x,y) (((x)+(y)-1)/(y)) // round up
#define fi first
#define se second
#define eb emplace_back
#define fcout cout << fixed << setprecision(15)


using namespace std;
using ll  = long long;
using P   = pair<int,int>;
using vi  = vector<int>;
using vvi = vector<vi>;
using vp  = vector<P>;
using vl  = vector<ll>;

template<typename T> void Yes(T flag) {
  cout << (flag ? "Yes" : "No") << endl;
}

template<typename T> void pv(vector<T> vec) {
  cout << "[";
  for(auto& v : vec) { cout << v << ","; }
  cout << "]" << endl;
}

template<>
void pv(vector<P> vec) {
  cout << "[";
  for(auto& v : vec) {
    cout << "<" << v.fi << ","<< v.se << ">" << ",";
  }
  cout << "]" << endl;
}

template<typename T> void pv2(vector<vector<T>> vec) {
  for(auto& v : vec) pv(v);
}

int main() {
  ll h,w;
  cin >> h >> w;
  if(h%3==0 or w%3==0) {
    cout << 0 << endl;
    return 0;
  }

  ll mi = min(h,w);
  ll ma = max(h,w);

  ll ss = mi * ma;
  ll ans = 100000001;
  orep(i,ma/2) {
    ll t = i * mi;
    ll r = (ma - i)*(mi/2);
    ll s = ss - t - r;
    ll mmi = min(t,r);
    mmi = min(mmi,s);
    ll mma = max(t,r);
    mma = max(s,mma);
    ans = min(ans,mma-mmi);

    r = mi*((ma-i)/2);
    s = ss - t - r;
    mmi = min(t,r);
    mmi = min(mmi,s);
    mma = max(t,r);
    mma = max(s,mma);
    ans = min(ans,mma-mmi);
  }
  ll t = mi;
  mi = ma;
  ma = t;
  orep(i,ma/2) {
    ll t = i * mi;
    ll r = (ma - i)*(mi/2);
    ll s = ss - t - r;
    ll mmi = min(t,r);
    mmi = min(mmi,s);
    ll mma = max(t,r);
    mma = max(s,mma);
    ans = min(ans,mma-mmi);

    r = mi*((ma-i)/2);
    s = ss - t - r;
    mmi = min(t,r);
    mmi = min(mmi,s);
    mma = max(t,r);
    mma = max(s,mma);
    ans = min(ans,mma-mmi);
  }
  cout << ans << endl;


  return 0;
}