#include <bits/stdc++.h>
using namespace std;
const int MAXN = 505;
const int MAXM = MAXN * MAXN * 2;
int n, m, que[MAXM], head, tail, pre[MAXN], tim, g[MAXN], tot, match[MAXN],
    fa[MAXN], type[MAXN], tic[MAXN];
int u[MAXN], v[MAXN];
struct edge {
  int to, next;
} e[MAXM];
int findf(int x) { return fa[x] == x ? fa[x] : fa[x] = findf(fa[x]); }
void add_edge(int from, int to) {
  e[++tot].to = to;
  e[tot].next = g[from];
  g[from] = tot;
}
void init() {
  tim = 0;
  tot = 0;
  for (int i = 0; i <= n; ++i) {
    g[i] = 0;
    match[i] = 0;
    tic[i] = 0;
  }
}
int lca(int x, int y) {
  ++tim;
  while (1) {
    if (x) {
      x = findf(x);
      if (tic[x] == tim) {
        return x;
      } else {
        tic[x] = tim;
        x = pre[match[x]];
      }
    }
    swap(x, y);
  }
}
void shrink(int x, int y, int p) {
  while (findf(x) != p) {
    pre[x] = y, y = match[x];
    if (type[y] == 2) type[y] = 1, que[++tail] = y;
    if (findf(x) == x) fa[x] = p;
    if (findf(y) == y) fa[y] = p;
    x = pre[y];
  }
}
bool aug(int s) {
  for (int i = 1; i <= n; ++i) {
    fa[i] = i;
    type[i] = 0;
    pre[i] = 0;
  }
  head = 0;
  tail = 1;
  que[tail] = s;
  type[s] = 1;
  int t = 0;
  while (head < tail) {
    int x = que[++head];
    for (int i = g[x]; i; i = e[i].next) {
      if (findf(e[i].to) == findf(x) || type[e[i].to] == 2) continue;
      if (!type[e[i].to]) {
        type[e[i].to] = 2, pre[e[i].to] = x;
        if (!match[e[i].to]) {
          int last, tmp;
          for (int now = e[i].to; now; now = last) {
            tmp = pre[now];
            last = match[tmp];
            match[now] = tmp;
            match[tmp] = now;
          }
          return true;
        }
        type[match[e[i].to]] = 1;
        que[++tail] = match[e[i].to];
      } else if (type[e[i].to] == 1) {
        int l = lca(x, e[i].to);
        shrink(x, e[i].to, l);
        shrink(e[i].to, x, l);
      }
    }
  }
  return false;
}
int EMA() {
  int ans = 0;
  for (int i = 1; i <= n; ++i) {
    ans += (!match[i] && aug(i));
  }
  return ans;
}
long long n1, m1;
int hash1(int x, int y) { return (x - 1) * m1 + y; }
const int dx[12] = {-3, -2, -1, 0, 1, 2, 3, 2, 1, 0, -1, -2};
const int dy[12] = {0, 1, 2, 3, 2, 1, 0, -1, -2, -3, -2, -1};
bool check1(int x, int y) {
  if (x > n1 || y > m1 || x < 1 || y < 1) return false;
  return true;
}
int main() {
  while (scanf("%I64d %I64d", &n1, &m1) != EOF) {
    if (n1 <= 10 && m1 <= 10) {
      n = n1 * m1;
      init();
      for (int i = 1; i <= n1; ++i) {
        for (int j = 1; j <= m1; ++j) {
          for (int k = 0; k < 12; ++k) {
            if (check1(i + dx[k], j + dy[k])) {
              add_edge(hash1(i, j), hash1(i + dx[k], j + dy[k]));
              add_edge(hash1(i + dx[k], j + dy[k]), hash1(i, j));
            }
          }
        }
      }
      cout << EMA() * 2 << endl;
    } else {
      if (n1 > m1) swap(n1, m1);
      if (n1 == 1) {
        if (m1 % 6 <= 3) {
          printf("%I64d\n", m1 / 6 * 6);
        } else if (m1 % 6 == 4) {
          printf("%I64d\n", m1 / 6 * 6 + 2);
        } else if (m1 % 6 == 5) {
          printf("%I64d\n", m1 / 6 * 6 + 4);
        }
        continue;
      }
      if ((n1 & 1) && (m1 & 1)) {
        printf("%I64d\n", n1 * m1 - 1);
      } else {
        printf("%I64d\n", n1 * m1);
      }
    }
  }
  return 0;
}
