#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 5;
struct MaxBipartite {
  int N, res;
  vector<int> g[MAXN];
  int predecessor[MAXN], matched[MAXN], x[MAXN];
  MaxBipartite(int n) : N(n), res(0) { memset(matched, -1, sizeof(matched)); }
  void addEdge(int i, int j) {
    g[i].push_back(j);
    g[j].push_back(i);
    if (matched[i] == -1 && matched[j] == -1) {
      matched[i] = j;
      matched[j] = i;
      ++res;
    }
  }
  int bfs(int i) {
    int last = -1;
    queue<int> q;
    q.push(i);
    while (!q.empty()) {
      int x = q.front();
      q.pop();
      for (auto &j : g[x]) {
        if (predecessor[j] == -1) {
          predecessor[j] = x;
          if (matched[j] == -1) {
            last = j;
            break;
          } else {
            q.push(matched[j]);
          }
        }
      }
      if (last != -1) break;
    }
    if (last != -1) {
      int cur = last;
      while (cur != -1) {
        int tmp = matched[predecessor[cur]];
        matched[cur] = predecessor[cur];
        matched[matched[cur]] = cur;
        cur = tmp;
      }
    }
    return (last != -1);
  }
  void dfs(int i, int cur) {
    x[i] = cur;
    for (auto &j : g[i]) {
      if (x[j] == -1) dfs(j, !cur);
    }
  }
  int MaxMatching(int n) {
    memset(x, -1, sizeof(x));
    for (int i = 0; i < n; ++i) {
      if (x[i] == -1) {
        dfs(i, 0);
      }
    }
    for (int i = 0; i < n; ++i) {
      if (matched[i] == -1 && x[i] == 0) {
        memset(predecessor, -1, sizeof(predecessor));
        res += bfs(i);
      }
    }
    return res;
  }
};
int get(int i, int j, int n) { return ((i - 1) * n) + (j - 1); }
int main() {
  std::ios::sync_with_stdio(false);
  int dx[8] = {-2, -2, 2, 2, -1, -1, 1, 1};
  int dy[8] = {-1, 1, -1, 1, -2, 2, -2, 2};
  int n, m;
  cin >> n >> m;
  MaxBipartite *mb = new MaxBipartite(n * m);
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      for (int k = 0; k < 8; ++k) {
        int ii = i + dx[k];
        int jj = j + dy[k];
        if (ii <= n && ii > 0 && jj <= m && jj > 0) {
          if (get(i, j, m) < get(ii, jj, m)) {
            mb->addEdge(get(i, j, m), get(ii, jj, m));
          }
        }
      }
    }
  }
  cout << n * m - mb->MaxMatching(n * m) << endl;
  return 0;
}
