#include <bits/stdc++.h>
using namespace std;
void __print(int x) { cerr << x; }
void __print(long x) { cerr << x; }
void __print(long long x) { cerr << x; }
void __print(unsigned x) { cerr << x; }
void __print(unsigned long x) { cerr << x; }
void __print(unsigned long long x) { cerr << x; }
void __print(float x) { cerr << x; }
void __print(double x) { cerr << x; }
void __print(long double x) { cerr << x; }
void __print(char x) { cerr << '\'' << x << '\''; }
void __print(const char *x) { cerr << '\"' << x << '\"'; }
void __print(const string &x) { cerr << '\"' << x << '\"'; }
void __print(bool x) { cerr << (x ? "true" : "false"); }
template <typename T, typename V>
void __print(const pair<T, V> &x) {
  cerr << '{';
  __print(x.first);
  cerr << ',';
  __print(x.second);
  cerr << '}';
}
template <typename T>
void __print(const T &x) {
  int f = 0;
  cerr << '{';
  for (auto &i : x) cerr << (f++ ? "," : ""), __print(i);
  cerr << "}";
}
void _print() { cerr << "]\n"; }
template <typename T, typename... V>
void _print(T t, V... v) {
  __print(t);
  if (sizeof...(v)) cerr << ", ";
  _print(v...);
}
const int MAXN = 1e5 + 5;
const long long INF = 1e9;
struct maxFlow {
  vector<pair<int, int> > e[MAXN];
  vector<long long> cap[MAXN];
  int level[MAXN];
  int nxt[MAXN];
  int s, t;
  int N;
  queue<int> q;
  void init(int n) {
    N = n;
    for (int i = 0; i < N; i++) e[i].clear(), cap[i].clear();
  }
  void addEdge(int x, int y, long long cxy, long long cyx) {
    e[x].push_back({y, cap[y].size()});
    e[y].push_back({x, cap[x].size()});
    cap[x].push_back(cxy);
    cap[y].push_back(cyx);
  }
  bool bfs() {
    while (!q.empty()) q.pop();
    for (int i = 0; i < N; i++) level[i] = -1;
    level[s] = 0;
    q.push(s);
    while (!q.empty()) {
      int p = q.front();
      q.pop();
      if (p == t) return true;
      for (int i = 0; i < (int)e[p].size(); i++) {
        int x = e[p][i].first;
        if (level[x] == -1 && cap[p][i] != 0) {
          level[x] = level[p] + 1;
          q.push(x);
        }
      }
    }
    return false;
  }
  long long augment(int x, long long c) {
    if (x == t) return c;
    for (int &i = nxt[x]; i < (int)e[x].size(); i++) {
      int y = e[x][i].first;
      if (cap[x][i] > 0 && level[y] == level[x] + 1) {
        long long tempFlow = augment(y, min(c, cap[x][i]));
        if (tempFlow > 0) {
          cap[x][i] -= tempFlow;
          cap[y][e[x][i].second] += tempFlow;
          return tempFlow;
        }
      }
    }
    return 0;
  }
  long long solve(int source, int sink) {
    s = source, t = sink;
    long long ans = 0;
    while (bfs()) {
      long long flow = 0;
      for (int i = 0; i < N; i++) nxt[i] = 0;
      while (flow = augment(s, INF)) ans += flow;
    }
    return ans;
  }
};
int nn, mm;
vector<int> dx = {-3, 0, 2, 2, -2, -2, 1, 1, -1, -1, 3, 0};
vector<int> dy = {0, -3, -1, 1, 1, -1, 2, -2, 2, -2, 0, 3};
int getId(int x, int y) { return (x * mm + y); }
bool isValid(int x, int y) { return (x >= 0 && y >= 0 && x < nn && y < mm); }
int main() {
  ios_base ::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  long long n, m;
  cin >> n >> m;
  nn = n % 300, mm = m % 300;
  maxFlow flowGraph;
  flowGraph.init(nn * mm + 2);
  int source = nn * mm, sink = source + 1;
  for (int i = 0; i < nn; i++) {
    for (int j = 0; j < mm; j++) {
      if ((i + j) & 1) {
        flowGraph.addEdge(source, getId(i, j), 2, 0);
        for (int k = 0; k < 12; k++) {
          int newX = i + dx[k], newY = j + dy[k];
          if (isValid(newX, newY)) {
            flowGraph.addEdge(getId(i, j), getId(newX, newY), INF, 0);
          }
        }
      } else {
        flowGraph.addEdge(getId(i, j), sink, 2, 0);
      }
    }
  }
  cout << n * m - (nn * mm - flowGraph.solve(source, sink));
  return 0;
}
