#include <bits/stdc++.h>
using namespace std;
int n, m;
int ans;
int map[100][100];
bool stay[100][100];
bool crawl[100][100];
bool flag;
int dx[5] = {0, 0, 1, 0, -1};
int dy[5] = {0, 1, 0, -1, 0};
void nextxy(int &x, int &y) {
  while (1) {
    if (!crawl[x][y]) return;
    if (y == m - 1) {
      x++;
      y = 0;
    } else
      y++;
    if (x == n) return;
  }
}
void out() {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (stay[i][j]) printf("P(%d,%d),,", i, j);
    }
  }
  printf("\n");
}
void dfs(int cx, int cy, int s) {
  if (flag) return;
  if (s == 0) {
    if (cx == n) {
      flag = true;
    }
    return;
  }
  if (cx == n) {
    return;
  }
  int nx, ny, x, y;
  for (int i = 0; i < 3; i++) {
    x = cx + dx[i];
    y = cy + dy[i];
    if (!stay[x][y]) {
      int st[5];
      stay[x][y] = true;
      int tot = 0;
      int j;
      for (j = 0; j < 5; j++) {
        nx = x + dx[j];
        ny = y + dy[j];
        if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
        if (!crawl[nx][ny]) {
          crawl[nx][ny] = true;
          st[tot++] = nx * m + ny;
        }
      }
      x = cx, y = cy;
      nextxy(x, y);
      dfs(x, y, s - 1);
      stay[cx + dx[i]][cy + dy[i]] = false;
      for (j = 0; j < tot; j++) crawl[st[j] / m][st[j] % m] = false;
    }
  }
}
bool pan(int s) {
  flag = false;
  memset(stay, 0, sizeof(stay));
  memset(crawl, 0, sizeof(crawl));
  dfs(0, 0, s);
  return flag;
}
void solve() {
  int l, r, mid;
  l = 1, r = n * m;
  int ji = r;
  for (int i = l; i <= r; i++) {
    if (pan(i)) {
      printf("%d\n", n * m - i);
      break;
    }
  }
}
int main() {
  while (~scanf("%d%d", &n, &m)) {
    if (n > m) swap(n, m);
    if (n == 1) {
      printf("%d\n", n * m - (m + 2) / 3);
      continue;
    }
    if (n == 2) {
      printf("%d\n", n * m - m / 2 - 1);
      continue;
    }
    solve();
  }
  return 0;
}
