#include <bits/stdc++.h>
using namespace std;
int dp[40][150][150], m, n, ans = INT_MAX;
bool check(int maski, int maski1, int maski2) {
  if (!(((maski1 >> 0) & 1) || ((maski1 >> 1) & 1) || ((maski2 >> 0) & 1) ||
        ((maski >> 0) & 1)))
    return false;
  for (int i = 1; i < m; i++) {
    if (!(((maski1 >> i) & 1) || ((maski1 >> (i - 1)) & 1) ||
          ((maski1 >> (i + 1)) & 1) || ((maski2 >> i) & 1) ||
          ((maski >> i) & 1)))
      return false;
  }
  return true;
}
int main() {
  cin >> n >> m;
  if (n == 1 && m == 1) {
    cout << 0 << endl;
    return 0;
  }
  if (m > n) swap(n, m);
  const int X = (1 << m);
  for (int i = 0; i < X; i++) {
    for (int j = 0; j < X; j++) {
      if (check(i, j, 0)) {
        dp[1][i][j] = __builtin_popcount(i) + __builtin_popcount(j);
      } else
        dp[1][i][j] = -1;
    }
  }
  for (int i = 2; i <= n; i++) {
    for (int j = 0; j < X; j++) {
      for (int z = 0; z < X; z++) {
        dp[i][j][z] = INT_MAX;
        for (int k = 0; k < X; k++) {
          if (check(j, z, k)) {
            if (dp[i - 1][z][k] != -1)
              dp[i][j][z] =
                  min(dp[i][j][z], dp[i - 1][z][k] + __builtin_popcount(j));
          }
        }
      }
    }
  }
  for (int i = 0; i < (X); i++) {
    ans = min(ans, dp[n][0][i]);
  }
  cout << (n * m) - ans << endl;
  return 0;
}
