#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int dp[50][70][70];
int n, m;
int all(int x) {
  int res = 1 << x;
  if (x != n - 1) res |= 1 << x + 1;
  if (x != 0) res |= 1 << x - 1;
  return res;
}
void dfs(int now, int i, int j, int k, int cost, int nk) {
  if (now == n) {
    dp[i][k][nk] = min(dp[i][k][nk], cost);
    return;
  }
  dfs(now + 1, i, j, k | all(now), cost + 1, nk | (1 << now));
  if (j >> now & 1) dfs(now + 1, i, j, k, cost, nk);
}
int calc(int j, int k) {
  int res = 0;
  for (int i = 0; i < n; i++) {
    if (!(j >> i & 1))
      k |= all(i), res++;
    else if (i && !(k >> i - 1 & 1))
      k |= all(i), res++;
  }
  if (!(k >> n - 1 & 1)) res++;
  return res;
}
int main() {
  scanf("%d%d", &n, &m);
  if (n > m) swap(n, m);
  if (n == 1) {
    printf("%d\n", n * m - (m + 2) / 3);
    return 0;
  }
  memset(dp, INF, sizeof(dp));
  dp[0][(1 << n) - 1][(1 << n) - 1] = 0;
  for (int i = 1; i <= m; i++) {
    for (int j = 0; j < (1 << n); j++) {
      for (int k = 0; k < (1 << n); k++) {
        if (dp[i - 1][j][k] == INF) continue;
        dfs(0, i, j, k, dp[i - 1][j][k], 0);
      }
    }
  }
  int ans = INF;
  for (int j = 0; j < (1 << n); j++) {
    for (int k = 0; k < (1 << n); k++) {
      if (dp[m][j][k] != INF) ans = min(ans, dp[m][j][k] + calc(j, k));
    }
  }
  printf("%d\n", n * m - ans);
  return 0;
}
