#include <bits/stdc++.h>
using namespace std;
const int MAX = 1000005;
vector<int> adj_up[MAX], adj_down[MAX];
int mate_up[MAX], mate_down[MAX], ans, n, m;
bool mark[MAX], found;
void dfs(int p, int v) {
  mark[v] = true;
  int tmp = mate_up[v];
  for (int i = 0; i < adj_up[v].size(); i++) {
    int u = adj_up[v][i];
    if (mate_down[u] == -1) {
      mate_down[u] = v;
      mate_up[v] = u;
      if (mate_up[v] != tmp) {
        if (p != -1) {
          mate_down[tmp] = p;
          mate_up[p] = tmp;
        } else
          mate_down[tmp] = -1;
      }
      found = true;
      return;
    }
    if (!mark[mate_down[u]]) dfs(v, mate_down[u]);
    if (mate_up[v] != tmp) {
      if (p != -1) {
        mate_down[tmp] = p;
        mate_up[p] = tmp;
      } else
        mate_down[tmp] = -1;
      return;
    }
  }
}
int id(int x, int y) { return (x - 1) * m + y; }
int main() {
  memset(mate_up, -1, sizeof(mate_up));
  memset(mate_down, -1, sizeof(mate_down));
  scanf("%d%d", &n, &m);
  int dx[8] = {-2, -2, -1, -1, 1, 1, 2, 2};
  int dy[8] = {-1, +1, -2, +2, -2, +2, -1, +1};
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      for (int k = 0; k < 8; k++) {
        int x = i + dx[k];
        int y = j + dy[k];
        if (x >= 1 && x <= n && y >= 1 && y <= m) {
          if ((x + y) % 2) {
            adj_up[id(x, y)].push_back(id(i, j));
            adj_down[id(i, j)].push_back(id(x, y));
          } else {
            adj_down[id(x, y)].push_back(id(i, j));
            adj_up[id(i, j)].push_back(id(x, y));
          }
        }
      }
  while (true) {
    memset(mark, false, sizeof(mark));
    found = false;
    for (int i = 1; i < MAX; i++)
      if (mate_up[i] == -1) dfs(-1, i);
    if (found == false) break;
  }
  for (int i = 1; i < MAX; i++) ans += (mate_up[i] != -1);
  printf("%d", n * m - ans);
  return 0;
}
