#include <bits/stdc++.h>
using namespace std;
const int dir_x[8] = {-2, -2, -1, -1, +1, +1, +2, +2};
const int dir_y[8] = {-1, +1, -2, +2, -2, +2, -1, +1};
int n, m, ans, dist_x[1000005], dist_y[1000005], mate_x[1000005],
    mate_y[1000005];
vector<int> adj[1000005];
queue<int> Q;
bool bfs() {
  bool found = false;
  for (int i = 0; i < (n * m); i++) {
    if (mate_x[i] == -1) Q.push(i);
    dist_x[i] = dist_y[i] = 0;
  }
  while (!Q.empty()) {
    int v = Q.front();
    Q.pop();
    for (int i = 0; i < (int)adj[v].size(); i++) {
      if (dist_y[adj[v][i]] == 0) {
        dist_y[adj[v][i]] = dist_x[v] + 1;
        if (mate_y[adj[v][i]] == -1)
          found = true;
        else {
          dist_x[mate_y[adj[v][i]]] = dist_y[adj[v][i]] + 1;
          Q.push(mate_y[adj[v][i]]);
        }
      }
    }
  }
  return found;
}
bool dfs(int v) {
  for (int i = 0; i < (int)adj[v].size(); i++) {
    if (dist_y[adj[v][i]] == dist_x[v] + 1) {
      dist_y[adj[v][i]] = 0;
      if (mate_y[adj[v][i]] == -1 || dfs(mate_y[adj[v][i]])) {
        mate_x[v] = adj[v][i];
        mate_y[adj[v][i]] = v;
        return true;
      }
    }
  }
  return false;
}
int hopcroft_karp() {
  memset(mate_x, -1, sizeof mate_x);
  memset(mate_y, -1, sizeof mate_y);
  int matching = 0;
  while (bfs())
    for (int i = 0; i < (n * m); i++)
      if (mate_x[i] == -1 && dfs(i)) matching++;
  return matching;
}
int get_id(int l, int c) { return (l * m + c); }
int num[1003][1003];
int main() {
  scanf("%d %d", &n, &m);
  int cnt = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) num[i][j] = cnt++;
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      for (int k = 0; k < 8; k++) {
        int x = i + dir_x[k];
        int y = j + dir_y[k];
        if (x > 0 && x <= n && y > 0 && y <= m) {
          adj[num[i][j]].push_back(num[x][y]);
        }
      }
    }
  }
  ans = (n * m) - (hopcroft_karp() / 2);
  printf("%d\n", ans);
  return 0;
}
