#include <bits/stdc++.h>
using namespace std;
int N, M, all, all2;
int op[8];
int dp[44][1 << 8][1 << 8], sol;
int gain[1 << 8];
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin >> N >> M;
  if (N > M) swap(N, M);
  all = 1 << N;
  all2 = 1;
  for (int I = 0; I < N; I++) all2 *= 5;
  for (int I = 0; I <= M; I++)
    for (int m = 0; m < all; m++)
      for (int m2 = 0; m2 < all; m2++) dp[I][m][m2] = 1e9;
  sol = N * M;
  for (int m = 0; m < all; m++) gain[m] = __builtin_popcount(m);
  dp[0][0][0] = 0;
  for (int I = 1; I <= M; I++) {
    for (int mop = 0; mop < all2; mop++) {
      memset(op, 0, sizeof(op));
      int nprev = 0;
      int ncurr = 0;
      int nnext = 0;
      bool ok = true;
      int tmp = mop;
      for (int K = 0; K < N; K++) {
        op[K] = tmp % 5;
        tmp /= 5;
        if (K == 1 - 1 && op[K] == 0) ok = false;
        if (K == N - 1 && op[K] == 2) ok = false;
        if (op[K] == 0) ncurr |= (1 << (K - 1));
        if (op[K] == 1) nprev |= (1 << (K));
        if (op[K] == 2) ncurr |= (1 << (K + 1));
        if (op[K] == 3) nnext |= (1 << (K));
        if (op[K] == 4) ncurr |= (1 << (K));
      }
      if (!ok) continue;
      for (int prev = 0; prev < all; prev++)
        for (int curr = 0; curr < all; curr++) {
          int tprev = prev | nprev;
          int tcurr = curr | ncurr;
          int tnext = nnext;
          if (I == 1) {
            if (tprev != 0) continue;
          }
          dp[I][tcurr][tnext] =
              min(dp[I][tcurr][tnext], dp[I - 1][prev][curr] + gain[tprev]);
        }
    }
  }
  for (int m = 0; m < all; m++)
    if (sol > dp[M][m][0] + gain[m]) sol = min(sol, dp[M][m][0] + gain[m]);
  cout << (N * M) - sol << endl;
}
