#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n , m;
const int N = 20;
int vis[N][N] , t[N][N];
int ans;
void dfs(int x , int y , int blocks){
if(x == n && y == m + 1){
ans = max(ans , blocks);
return ;
}
if(y > m){
dfs(x + 1 , 1 , blocks);
return ;
}
ans = max(ans , blocks);
if(!vis[x][y] && !vis[x + 1][y] && !vis[x + 2][y] && !vis[x + 1][y + 1] && !vis[x + 1][y + 2]){
if(t[x][y] <= blocks + 1){
vis[x][y] = vis[x + 1][y] = vis[x + 2][y] = vis[x + 1][y + 1] = vis[x + 1][y + 2] = 1;
t[x][y] = blocks + 1;
dfs(x , y + 1 , blocks + 1);
vis[x][y] = vis[x + 1][y] = vis[x + 2][y] = vis[x + 1][y + 1] = vis[x + 1][y + 2] = 0;
}
}
if(!vis[x][y] && !vis[x + 1][y] && !vis[x + 2][y] && !vis[x + 2][y - 1] && !vis[x + 2][y + 1]){
if(t[x][y] <= blocks + 1){
vis[x][y] = vis[x + 1][y] = vis[x + 2][y] = vis[x + 2][y - 1] = vis[x + 2][y + 1] = 1;
t[x][y] = blocks + 1;
dfs(x , y + 1 , blocks + 1);
vis[x][y] = vis[x + 1][y] = vis[x + 2][y] = vis[x + 2][y - 1] = vis[x + 2][y + 1] = 0;
}
}
if(!vis[x][y] && !vis[x + 1][y] && !vis[x + 2][y] && !vis[x + 1][y - 1] && !vis[x + 1][y - 2]){
if(t[x][y] <= blocks + 1){
vis[x][y] = vis[x + 1][y] = vis[x + 2][y] = vis[x + 1][y - 1] = vis[x + 1][y - 2] = 1;
t[x][y] = blocks + 1;
dfs(x , y + 1 , blocks + 1);
vis[x][y] = vis[x + 1][y] = vis[x + 2][y] = vis[x + 1][y - 1] = vis[x + 1][y - 2] = 0;
}
}
if(!vis[x][y] && !vis[x][y + 1] && !vis[x][y + 2] && !vis[x + 1][y + 1] && !vis[x + 2][y + 2]){
if(t[x][y] <= blocks + 1){
vis[x][y] = vis[x][y + 1] = vis[x][y + 2] = vis[x + 1][y + 1] = vis[x + 2][y + 2] = 1;
t[x][y] = blocks + 1;
dfs(x , y + 1 , blocks + 1);
vis[x][y] = vis[x][y + 1] = vis[x][y + 2] = vis[x + 1][y + 1] = vis[x + 2][y + 2] = 0;
}
}
dfs(x , y + 1 , blocks);
}
int main(){
cin >> n >> m;
for(int i = 0;i <= m + 1;i++){
vis[0][i] = 1;
vis[n + 1][i] = 1;
}
for(int i = 0;i <= n + 1;i++){
vis[i][0] = 1;
vis[i][m + 1] = 1;
}
dfs(1 , 1 , 0);
cout << ans << endl;
return 0;
}