#include <bits/stdc++.h>
#include <boost/range/algorithm.hpp>
#include <boost/range/numeric.hpp>
#include <boost/integer/common_factor.hpp>
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>

using std::string;
using std::vector;
using std::set;
using std::multiset;
using std::unordered_set;
using std::map;
using std::multimap;
using std::unordered_map;
using std::pair;
using std::cin;
using std::cout;

using boost::multiprecision::cpp_int;
using cpp_dec_float_1000 = boost::multiprecision::number<boost::multiprecision::cpp_dec_float<1000, boost::int128_type>>;

typedef uintmax_t    ull;
typedef intmax_t     ll;
typedef uint64_t     ul;
typedef uint32_t     ui;
typedef uint8_t      uc;

constexpr char CRLF  = '\n';
constexpr char SPACE = ' ';
constexpr char VECTOR_COUT_SEPARATOR = SPACE;
constexpr ll INF = 1000'000'007;
constexpr int MOD = 1000'000'007;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
template<class T> std::ostream& operator<< (std::ostream& os, const std::vector<T>& vc) { for(auto it = vc.begin(); it != vc.end(); ++it) { if (std::next(it) == vc.end()) os << *it; else os << *it << VECTOR_COUT_SEPARATOR; } return os; }
template<class T1, class T2> inline std::ostream & operator<< (std::ostream & os, const std::pair<T1, T2> & p) { return os << p.first << ' ' << p.second; }
template<class T> T modinv(T a, T m) { T b = m, u = 1, v = 0; while (b) { T t = a / b; a -= t * b; boost::swap(a, b); u -= t * v; boost::swap(u, v); } u %= m; if (u < 0) u += m; return u; }
template<class T> inline bool isSosuu(const T& n) { if (n == T(1)) { return false; } for (T i = 2; i*i <= n; ++i) { if (n % i == 0) { return false; } } return true; }
template<class T> vector<vector<T>> split (const vector<T>& S, T delim) { vector<vector<T>> ret{}; vector<T> buff{}; for (auto c : S) { if (c == delim) { if (!buff.empty()) ret.push_back(buff); buff.clear(); } else { buff.push_back(c); } } if (!buff.empty()) ret.push_back(buff); return ret; }
template<class T> inline void printYesNo(const T& t) { cout << (t ? "Yes" : "No") << CRLF; }
template<class T = int64_t> T modpow(T N, T P, T M) { T ret{1}; N %= M; while (P) { if (P & 0x01) { ret *= N; ret %= M; } P >>= 1; N *= N; N %= M; } return ret; }

/** code for assert debug begin */
int gErr = 0;
#define ASSERT(p) if(!(p)){ gErr = 1; }else{ ; }
/** code for assert debug end */

struct Tmp
{
public:
  int N;
  Tmp(int N)
  : N(N)
  {}
};

void solve(void)
{
  ll H, W; cin >> H >> W;
  ll res = std::min({H, W});

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

  for (int h = 1; h < H; ++h) {
    auto h1 = H - h;
    auto s1 = h1 * W;
    if (h > h1) {
      auto w2 = W / 2;
      auto w3 = W - w2;
      auto s2 = h * w2;
      auto s3 = h * w3;
      chmin(res, std::max({s1, s2, s3}) - std::min({s1, s2, s3}));
    }
    
    ll ok = W;
    ll ng = 0;
    while (std::abs(ok - ng) > 1) {
      auto mid = (ok + ng) / 2;
      auto s2 = mid * h;
      if (s2 >= s1) {
        ok = mid;
      } else {
        ng = mid;
      }
    }
    auto w11 = ok;
    auto w12 = W - w11;
    if (w11 > 0 && w12 > 0) {
      auto s2 = w11 * h;
      auto s3 = w12 * h;
      auto m1 = std::min({s1, s2, s3});
      auto m2 = std::max({s1, s2, s3});
      chmin(res, m2 - m1);
    }
    auto w21 = w11 - 1;
    auto w22 = W - w21;
    if (w21 > 0 && w22 > 0) {
      auto s2 = w21 * h;
      auto s3 = w22 * h;
      auto m1 = std::min({s1, s2, s3});
      auto m2 = std::max({s1, s2, s3});
      chmin(res, m2 - m1);
    }
  }
  for (int w = 1; w <= W; ++w) {
    auto w1 = W - w;
    auto s1 = w1 * H;

    if (w > w1) {
      auto h2 = H / 2;
      auto h3 = H - h2;
      auto s2 = w * h2;
      auto s3 = w * h3;
      chmin(res, std::max({s1, s2, s3}) - std::min({s1, s2, s3}));
    }

    ll ok = H;
    ll ng = 0;
    while (std::abs(ok - ng) > 1) {
      auto mid = (ok + ng) / 2;
      auto s2 = mid * w;
      if (s2 >= s1) {
        ok = mid;
      } else {
        ng = mid;
      }
    }
    auto h11 = ok;
    auto h12 = H - h11;
    if (h11 > 0 && h12 > 0) {
      auto s2 = h11 * w;
      auto s3 = h12 * w;
      auto m1 = std::min({s1, s2, s3});
      auto m2 = std::max({s1, s2, s3});
      chmin(res, m2 - m1);
    }
    auto h21 = h11 - 1;
    auto h22 = H - h21;
    if (h21 > 0 && h22 > 0) {
      auto s2 = h21 * w;
      auto s3 = h22 * w;
      auto m1 = std::min({s1, s2, s3});
      auto m2 = std::max({s1, s2, s3});
      chmin(res, m2 - m1);
    }
  }
  cout << res << CRLF;
  return;
}

int main(void)
{
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(0);

  solve();

  return 0;
}


Measured memory_bytes: 256