#include <bits/stdc++.h>
int dp[100][100][100];
int num[100];
int n, m, top;
int min(int a, int b) {
  if (a < b) return a;
  return b;
}
int check(int x) {
  int t1 = x | (x >> 1);
  int t2 = x | ((x << 1) & ((1 << m) - 1));
  return (t1 | t2);
}
int ok(int x, int y, int z) {
  int t2 = check(y);
  if (((t2 | x | z) == top)) return 1;
  return 0;
}
int count(int x) {
  int cnt = 0;
  while (x) {
    cnt++;
    x &= (x - 1);
  }
  return cnt;
}
int main() {
  int i, j, k, t;
  while (scanf("%d%d", &n, &m) != EOF) {
    if (n < m) {
      int t = n;
      n = m;
      m = t;
    }
    if (n * m == 1) {
      printf("%d\n", 0);
      continue;
    }
    top = (1 << m) - 1;
    for (i = 0; i <= n; i++) {
      for (j = 0; j <= top; j++)
        for (t = 0; t <= top; t++) dp[i][j][t] = 0xfffffff;
    }
    if (n == 2 && m == 1) {
      printf("%d\n", 1);
      continue;
    }
    if (n == 2 && m == 2) {
      printf("%d\n", 2);
      continue;
    }
    for (i = 0; i <= top; i++) num[i] = count(i);
    for (i = 0; i <= top; i++) {
      for (j = 0; j <= top; j++) {
        if (ok(i, j, 0)) dp[2][i][j] = num[i] + num[j];
      }
    }
    for (i = 3; i < n; i++) {
      for (j = 0; j <= top; j++) {
        for (t = 0; t <= top; t++) {
          for (k = 0; k <= top; k++) {
            if (dp[i - 1][t][k] == 0xfffffff) continue;
            if (ok(j, t, k)) {
              dp[i][j][t] = min(dp[i][j][t], dp[i - 1][t][k] + num[j]);
            }
          }
        }
      }
    }
    int ans = 0xfffffff;
    for (i = 0; i <= top; i++) {
      for (j = 0; j <= top; j++) {
        for (k = 0; k <= top; k++) {
          if (dp[n - 1][j][k] == 0xfffffff) continue;
          if (ok(i, j, k) && ok(j, i, 0)) {
            ans = min(ans, dp[n - 1][j][k] + num[i]);
          }
        }
      }
    }
    printf("%d\n", n * m - ans);
  }
  return 0;
}
