#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <functional>
#include <limits.h>
#include <set>
#include <map>
#include <tuple>
using namespace std;



#define ll long long
#define ull unsigned long long
#define rep(i,N) for (ll i=0;i<N;i++)
#define loop(i,N,M) for(ll i=N;i<M;i++)
#define MAX(v) *max_element(v.begin(),v.end())
#define MIN(v) *min_element(v.begin(),v.end())
#define SORTL2S(type,v) sort(v.begin(),v.end(),greater<type>())
#define SORTS2L(type,v) sort(v.begin(),v.end())
#define SORTMF(v,func) sort(v.begin(),v.end(),func)

ll debugFlag = false;
template<typename T> void debug(T&);
template<typename T> void debug(T&, bool);
template<typename T> void debug(vector<T>&);
template<typename T> void debug(vector<T>&, bool);
template<typename T, typename U> void debug(pair<T, U>&);
template<typename T, typename U> void debug(pair<T, U>&, bool);

template<typename T>
void debug(T& obj) {
	debug(obj, true);
}

template<typename T>
void debug(T& obj, bool lnFlag) {
	if (!debugFlag) return;
	cout << obj;
	if (lnFlag) cout << endl;
}

template<typename T>
void debug(vector<T>& obj) {
	debug(obj, true);
}

template<typename T>
void debug(vector<T>& obj, bool lnFlag) {
	if (!debugFlag) return;
	cout << "[";
	rep(i, obj.size()) {
		if (i != 0) cout << ",";
		debug(obj[i], false);
	}
	cout << "]";
	if (lnFlag) cout << endl;
}

template<typename T, typename U>
void debug(pair<T, U>& obj) {
	debug(obj, true);
}

template<typename T, typename U>
void debug(pair<T, U>& obj, bool lnFlag) {
	if (!debugFlag) return;
	cout << "(";
	debug(obj.first, false);
	cout << ",";
	debug(obj.second, false);
	cout << ")";
	if (lnFlag) cout << endl;
}

template<typename T>
ll LongestIncreaseSubseq(vector<T>& vec) {

	vector<T> dp(vec.size());

	ll maxpos = 0;

	rep(i, vec.size()) {

		ll pos = lower_bound(dp.begin(), dp.begin() + maxpos, vec[i]) - dp.begin();

		if (pos == maxpos) {
			maxpos++;
			dp[pos] = vec[i];
		}
		else if (dp[pos] > vec[i]) dp[pos] = vec[i];

		debug(dp);

	}

	return maxpos;
}

void solve() {

	ll H, W;
	cin >> H >> W;

	if (H % 3 == 0 || W % 3 == 0) {
		cout << 0;
		return;
	}

	ll ans = min(H, W);

	ll tmpmn = min(W / 3 * H, min((W - W / 3)*(H / 2), (W - W / 3)*(H - H / 2)));
	ll tmpmx = max(W / 3 * H, max((W - W / 3)*(H / 2), (W - W / 3)*(H - H / 2)));

	ans = min(ans, tmpmx - tmpmn);

	tmpmn = min((W / 3 + 1)*H, min((W - W / 3 - 1)*	(H / 2), (W - W / 3 - 1)*(H - H / 2)));
	tmpmx = max((W / 3 + 1)*H, max((W - W / 3 - 1)*(H / 2), (W - W / 3 - 1)*(H - H / 2)));

	ans = min(ans, tmpmx - tmpmn);

	tmpmn = min(H / 3 * W, min((H - H / 3)*(W / 2), (H - H / 3)*(W - W / 2)));
	tmpmx = max(H / 3 * W, max((H - H / 3)*(W / 2), (H - H / 3)*(W - W / 2)));

	ans = min(ans, tmpmx - tmpmn);

	tmpmn = min((H / 3 + 1)*W, min((H - H / 3 - 1)*(W / 2), (H - H / 3 - 1)*(W - W / 2)));
	tmpmx = max((H / 3 + 1)*W, max((H - H / 3 - 1)*(W / 2), (H - H / 3 - 1)*(W - W / 2)));

	ans = min(ans, tmpmx - tmpmn);

	cout << ans;

}


int main(int argc, char* argv[]) {
	if (argc == 2 && string(argv[1]) == "debug") debugFlag = true;
	solve();
	return 0;
}


Measured memory_bytes: 256