#include <bits/stdc++.h>
using namespace std;
const int dmax = 8;
const int dx[dmax] = {1, 1, -1, -1, 2, 2, -2, -2};
const int dy[dmax] = {-2, 2, -2, 2, 1, -1, 1, -1};
const int rSize = 1010;
const int cSize = 1010;
const int queSize = (rSize + 3) * (cSize + 3);
int r, c, red, black;
bool arr[rSize][cSize] = {false};
struct bfsNode {
  int father, x, y, dist;
  bfsNode() {}
  bfsNode(int X, int Y, int DIST, int FATHER) {
    x = X;
    y = Y;
    dist = DIST;
    father = FATHER;
  }
  bfsNode(bfsNode expand, int d, int FATHER) {
    father = FATHER;
    x = expand.x;
    y = expand.y;
    int tx = x + dx[d];
    int ty = y + dy[d];
    dist = 3 - expand.dist;
    x = tx;
    y = ty;
  }
  bool inLimit() { return (x >= 0 && x < r && y >= 0 && y < c); }
} que[queSize];
int bfs(bfsNode Start) {
  arr[Start.x][Start.y] = true;
  red = 1;
  int head = 0, tail = 0;
  que[head++] = Start;
  while (tail < head) {
    for (int i = 0; i < dmax; i++) {
      bfsNode suc = bfsNode(que[tail], i, tail);
      if (suc.inLimit()) {
        if (!arr[suc.x][suc.y]) {
          arr[suc.x][suc.y] = true;
          if (suc.dist == 1)
            red++;
          else
            black++;
          que[head++] = suc;
        }
      }
    }
    tail++;
  }
  return -1;
}
int main() {
  while (cin >> r >> c) {
    int ans = 0;
    memset(arr, 0, sizeof(arr));
    for (int i = 0; i < r; i++)
      for (int j = 0; j < c; j++)
        if (!arr[i][j]) {
          red = black = 0;
          bfs(bfsNode(i, j, 1, 0));
          ans += max(red, black);
        }
    cout << ans << endl;
  }
  return 0;
}
