#include <bits/stdc++.h>
using namespace std;
const int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};
class DominatingSet {
  const int n;
  const long long Omega;
  vector<long long> mask, mask2;
  vector<vector<int> > adj;
  int dfs(int u, long long S, int tmp, int &ub) {
    if (S == Omega) {
      ub = tmp;
      return tmp;
    }
    if (u == n || tmp >= ub || (S | mask2[u]) != Omega) return n;
    return min(dfs(u + 1, S, tmp, ub), dfs(u + 1, S | mask[u], tmp + 1, ub));
  }

 public:
  DominatingSet(const vector<vector<int> > &A)
      : n(A.size()), Omega((1LL << A.size()) - 1), adj(A) {
    mask.resize(n);
    for (int u = 0; u < (n); u++) {
      mask[u] = 1LL << u;
      for (int i = 0; i < (adj[u].size()); i++) mask[u] |= 1LL << adj[u][i];
    }
    mask2.resize(n);
    mask2[n - 1] = mask[n - 1];
    for (int u = n - 1; u > 0; u--) mask2[u - 1] = mask[u - 1] | mask2[u];
  }
  int solve() {
    int ub = n;
    return dfs(0, 0, 0, ub);
  }
};
int main() {
  int m, n;
  scanf("%d%d", &m, &n);
  vector<vector<int> > adj(m * n);
  for (int i = 0; i < (m); i++)
    for (int j = 0; j < (n); j++)
      for (int k = 0; k < (4); k++) {
        int y = i + dy[k], x = j + dx[k];
        if (0 <= y && y < m && 0 <= x && x < n)
          adj[i * n + j].push_back(y * n + x);
      }
  printf("%d\n", m * n - DominatingSet(adj).solve());
  return 0;
}
