source_code: import java.util.ArrayList;
  import java.util.List;
  import java.util.InputMismatchException;
  import java.math.BigInteger;
  import java.util.Iterator;
  import java.io.*;
  import java.util.Comparator;
  import java.util.Arrays;
  import java.util.Collection;
  
  /**
   * Generated by Contest helper plug-in
   * Actual solution is at the bottom
   */
  public class Main {
  	public static void main(String[] args) {
  		InputReader in = new StreamInputReader(System.in);
  		PrintWriter out = new PrintWriter(System.out);
  		run(in, out);
  	}
  
  	public static void run(InputReader in, PrintWriter out) {
  		Solver solver = new TaskC();
  		solver.solve(1, in, out);
  		Exit.exit(in, out);
  	}
  }
  
  abstract class InputReader {
  	private boolean finished = false;
  
  	public abstract int read();
  
  	public int readInt() {
  		int c = read();
  		while (isSpaceChar(c))
  			c = read();
  		int sgn = 1;
  		if (c == '-') {
  			sgn = -1;
  			c = read();
  		}
  		int res = 0;
  		do {
  			if (c < '0' || c > '9')
  				throw new InputMismatchException();
  			res *= 10;
  			res += c - '0';
  			c = read();
  		} while (!isSpaceChar(c));
  		return res * sgn;
  	}
  
  	public String readString() {
  		int c = read();
  		while (isSpaceChar(c))
  			c = read();
  		StringBuffer res = new StringBuffer();
  		do {
  			res.appendCodePoint(c);
  			c = read();
  		} while (!isSpaceChar(c));
  		return res.toString();
  	}
  
  	private boolean isSpaceChar(int c) {
  		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
  	}
  
  	public void setFinished(boolean finished) {
  		this.finished = finished;
  	}
  
  	public abstract void close();
  }
  
  class StreamInputReader extends InputReader {
  	private InputStream stream;
  	private byte[] buf = new byte[1024];
  	private int curChar, numChars;
  
  	public StreamInputReader(InputStream stream) {
  		this.stream = stream;
  	}
  
  	public int read() {
  		if (numChars == -1)
  			throw new InputMismatchException();
  		if (curChar >= numChars) {
  			curChar = 0;
  			try {
  				numChars = stream.read(buf);
  			} catch (IOException e) {
  				throw new InputMismatchException();
  			}
  			if (numChars <= 0)
  				return -1;
  		}
  		return buf[curChar++];
  	}
  
  	public void close() {
  		try {
  			stream.close();
  		} catch (IOException ignored) {
  		}
  	}
  }
  
  class Exit {
  	private Exit() {
  	}
  
  	public static void exit(InputReader in, PrintWriter out) {
  		in.setFinished(true);
  		in.close();
  		out.close();
  	}
  }
  
  interface Solver {
  	public void solve(int testNumber, InputReader in, PrintWriter out);
  }
  
  class ArrayUtils {
  
  	public static void fill(int[][] array, int value) {
  		for (int[] row : array)
  			Arrays.fill(row, value);
  	}
  
  	public static void fill(int[][][] array, int value) {
  		for (int[][] subArray : array)
  			fill(subArray, value);
  	}
  
  	}
  
  class TaskC implements Solver {
  	public void solve(int testNumber, InputReader in, PrintWriter out) {
  		int rowCount = in.readInt();
  		int columnCount = in.readInt();
  		out.println(rowCount * columnCount - go(Math.min(rowCount, columnCount), Math.max(rowCount, columnCount)));
  	}
  
  	private int go(int rowCount, int columnCount) {
  		int[][][] result = new int[columnCount][rowCount][1 << (2 * rowCount)];
  		ArrayUtils.fill(result, -1);
  		return go(0, 0, (1 << rowCount) - 1, result);
  	}
  
  	private int go(int column, int row, int mask, int[][][] result) {
  		if (column == result.length)
  			return (mask == 0 ? 0 : Integer.MAX_VALUE / 2);
  		int length = result[column].length;
  		if (row == length)
  			return go(column + 1, 0, mask, result);
  		if (result[column][row][mask] != -1)
  			return result[column][row][mask];
  		result[column][row][mask] = Integer.MAX_VALUE / 2;
  		if ((mask >> (2 * length - 1) & 1) == 0)
  			result[column][row][mask] = go(column, row + 1, mask * 2 + (column == result.length - 1 ? 0 : 1), result);
  		int newMask = mask;
  		newMask &= ~(1 << (length - 1));
  		if (row != 0)
  			newMask &= ~(1 << length);
  		if (row != length - 1)
  			newMask &= ~(1 << (length - 2));
  		newMask *= 2;
  		newMask &= (1 << (2 * length)) - 1;
  		return result[column][row][mask] = Math.min(result[column][row][mask], 1 + go(column, row + 1, newMask, result));
  	}
  }
  
  