codeparrot/codecomplex huggingface dataset:
// Problem: 111_C. Petya and Spiders
// Time complexity: np
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.Map.Entry;

public class Solution implements Runnable {

	public static void main(String[] args) {
		(new Thread(new Solution())).start();
	}

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st;

	String nextToken() throws IOException {
		while (st == null || !st.hasMoreTokens()) {
			String r = in.readLine();
			if (r == null) return null;
			st = new StringTokenizer(r);
		}
		return st.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}
	
	int count(int q, int n) {
		int ans = 0;
		for (int i = 0; i < n; i++) {
			if (q % 3 != 1) ans++;
			q /= 3;
		}
		return ans;
	}
	
	int count2(int q, int n) {
		int ans = 0;
		for (int i = 0; i < n; i++) {
			if (q % 3 == 2) ans++;
			q /= 3;
		}
		return ans;
	}
	
	int sz;
	
	int[] decode(int q, int n) {
		int[] res = new int[n];
		for (int i = 0; i < n; i++) {
			res[i] = q % 3;
			q /= 3;
		}
		return res;
	}
	
	boolean[][] precalc(int n, int m) {
		boolean[][] res = new boolean[sz][sz];
		for (int i = 0; i < sz; i++) {
			int[] ai = decode(i, n);
			for (int j = 0; j < sz; j++) {
				int[] aj = decode(j, n);
				boolean f = true;
				for (int k = 0; k < n && f; k++) {
					if (aj[k] == 0) {
						f = false;
						if (k > 0 && aj[k - 1] == 1) f = true;
						if (k < n - 1 && aj[k + 1] == 1) f = true;
						if (ai[k] == 1) f = true;
					}
					if (f && ai[k] == 2) f = (aj[k] == 1);
				}
				res[i][j] = f;
			}
		}
		return res;
	}
	
	void solve() throws Exception {
		int n = nextInt();
		int m = nextInt();
		if (n > m) { int t = n; n = m; m = t; }
		sz = 1;
		for (int i = 0; i < n; i++) sz *= 3;
		boolean[][] a = precalc(n, m);
		int[][] d = new int[m + 1][sz];
		Arrays.fill(d[0], -1);
		d[0][0] = 0;
		for (int i = 1; i <= m; i++) {
			Arrays.fill(d[i], -1);
			for (int j = 0; j < sz; j++) {
				if (d[i - 1][j] != -1) {
					for (int k = 0; k < sz; k++) {
						if (a[j][k]) {
							d[i][k] = Math.max(d[i][k], d[i - 1][j] + count(k, n));
						}
					}
				}
			}
		}
		int ans = 0;
		for (int i = 0; i < sz; i++) if (count2(i, n) == 0) ans = Math.max(ans, d[m][i]);
		out.println(ans);
	}

	public void run() {
		Locale.setDefault(Locale.UK);
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
//			in = new BufferedReader(new FileReader("knights.in"));
//			out = new PrintWriter("knights.out");
			solve();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		} finally {
			out.flush();
		}
	}

}
// Problem: 111_C. Petya and Spiders
// Time complexity: np
import java.util.*;
import java.lang.*;
import java.math.*;
import java.io.*;

import static java.lang.Math.*;
import static java.util.Arrays.*;

public class C{
    Scanner sc=new Scanner(System.in);

    int INF=1<<28;
    double EPS=1e-9;

    int n, m;

    void run(){
        n=sc.nextInt();
        m=sc.nextInt();
        solve();
    }

    void solve(){
        if(n<m){
            int t=n;
            n=m;
            m=t;
        }
        int full=(1<<m)-1;
        int[][] dp=new int[1<<m][1<<m];
        int[][] tmp=new int[1<<m][1<<m];
        for(int i=0; i<1<<m; i++){
            fill(dp[i], INF);
        }
        for(int i=0; i<1<<m; i++){
            int b1=(i|(i>>1)|(i<<1))&full;
            int b2=i;
            dp[b1][b2]=Integer.bitCount(i);
            debug(Integer.toBinaryString(b1), dp[b1]);
        }
        debug();
        for(int j=0; j<n-1; j++){
            for(int i=0; i<1<<m; i++){
                System.arraycopy(dp[i], 0, tmp[i], 0, 1<<m);
                fill(dp[i], INF);
            }

            for(int b1=0; b1<1<<m; b1++){
                for(int b2=0; b2<1<<m; b2++){
                    for(int i=0; i<1<<m; i++){
                        if((b1|i)!=full){
                            continue;
                        }
                        if(false)
                            debug(Integer.toBinaryString(b1),
                                    Integer.toBinaryString(b2),
                                    Integer.toBinaryString(i));
                        int b=(i|(i>>1)|(i<<1))&full;
                        dp[b2|b][i]=min(dp[b2|b][i],
                                tmp[b1][b2]+Integer.bitCount(i));
                    }
                }
            }
            debug(j);
            for(int i=0; i<1<<m; i++){
                debug(Integer.toBinaryString(i), dp[i]);
            }
        }

        int min=INF;
        for(int i=0; i<1<<m; i++){
            min=min(min, dp[full][i]);
        }
        debug(min);
        int ans=m*n-min;
        debug("ans",ans);
        println(ans+"");
    }

    void println(String s){
        System.out.println(s);
    }

    void print(String s){
        System.out.print(s);
    }

    void debug(Object... os){
        // System.err.println(Arrays.deepToString(os));
    }

    public static void main(String[] args){
        new C().run();
    }
}
// Problem: 111_C. Petya and Spiders
// Time complexity: np
import java.util.*;
import java.lang.*;
import java.math.*;
import java.io.*;
import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;

public class P111C{
	Scanner sc=new Scanner(System.in);

	int INF=1<<28;
	double EPS=1e-9;

	int h, w;

	void run(){
		h=sc.nextInt();
		w=sc.nextInt();
		solve();
	}

	void solve(){
		n=w*h;
		g=new long[n];
		int[] dx={0, 0, -1, 1};
		int[] dy={-1, 1, 0, 0};
		for(int y=0; y<h; y++){
			for(int x=0; x<w; x++){
				for(int k=0; k<4; k++){
					int x2=x+dx[k];
					int y2=y+dy[k];
					if(x2>=0&&x2<w&&y2>=0&&y2<h){
						g[y*w+x]|=1L<<(y2*w+x2);
					}
				}
			}
		}
		mds=(1L<<n)-1;
		mds(0, 0, 0);
		println((n-Long.bitCount(mds))+"");
	}

	int n;
	long[] g;
	long mds;

	void mds(long choosed, long removed, long covered){
		if(Long.bitCount(choosed)>=Long.bitCount(mds))
			return;
		if(covered==((1L<<n)-1)){
			if(Long.bitCount(choosed)<Long.bitCount(mds))
				mds=choosed;
			return;
		}

		int k=-1;
		ArrayList<Integer> list=new ArrayList<Integer>();
		for(long remained=~removed&((1L<<n)-1); remained!=0; remained&=remained-1){
			int i=Long.numberOfTrailingZeros(remained);
			if((covered>>>i&1)==1){
				if(Long.bitCount(g[i]&~covered)==0){
					mds(choosed, removed|(1L<<i), covered);
					return;
				}else if(Long.bitCount(g[i]&~covered)==1
						&&(g[i]&~covered&~removed)!=0){
					mds(choosed, removed|(1L<<i), covered);
					return;
				}
			}else{
				if(Long.bitCount(g[i]&~removed)==0){
					mds(choosed|(1L<<i), removed|(1L<<i), covered|(1L<<i)|g[i]);
					return;
				}else if(Long.bitCount(g[i]&~removed)==1
						&&((g[i]&~removed)|(g[i]&~covered))==(g[i]&~removed)){
					int j=Long.numberOfTrailingZeros(g[i]&~removed);
					mds(choosed|(1L<<j), removed|(1L<<i)|(1L<<j), covered
							|(1L<<j)|g[j]);
					return;
				}
			}
			// if(k==-1||Long.bitCount(g[i]&~covered)>Long.bitCount(g[k]&~covered))
			// k=i;
			if(k==-1||Long.bitCount(g[i]&~covered)>Long.bitCount(g[k]&~covered)){
				list.clear();
				list.add(i);
				k=i;
			}else if(Long.bitCount(g[i]&~covered)==Long.bitCount(g[k]&~covered))
				list.add(i);
		}
		if(k==-1)
			return;
		
		k=list.get((int)(list.size()*random()));

		mds(choosed|(1L<<k), removed|(1L<<k), covered|(1L<<k)|g[k]);
		mds(choosed, removed|(1L<<k), covered);
	}

	void println(String s){
		System.out.println(s);
	}

	void print(String s){
		System.out.print(s);
	}

	void debug(Object... os){
		System.err.println(Arrays.deepToString(os));
	}

	public static void main(String[] args){
		Locale.setDefault(Locale.US);
		new P111C().run();
	}
}
// Problem: 111_C. Petya and Spiders
// Time complexity: np
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

/**
 * Author -
 * User: kansal
 * Date: 9/3/11
 * Time: 5:28 PM
 */
public class CF85C {
    public static void main(String[] args) {
        reader = new BufferedReader(new InputStreamReader(System.in));

        int height = nextInt(), width = nextInt();
        if (width > height) {
            int t = width;
            width = height;
            height = t;
        }

        final int INF = height * width + 10;
        final int ALL_BITS = (1 << width)  - 1;
        int[][][] dp = new int[height + 1][1 << width][1 << width];
        for (int[][] ints : dp) {
            for (int[] anInt : ints) {
                Arrays.fill(anInt, INF);
            }
        }

        dp[0][0][0] = 0;
        for(int r = 0; r < height; ++r) {
            for(int uncovered = 0; uncovered < (1 << width); ++uncovered) {
                for(int mask = 0; mask < (1 << width); ++mask) {
                    if (dp[r][uncovered][mask] == INF) {
                        continue;
                    }

                    for(int curMask = uncovered; curMask < (1 << width); curMask = (curMask + 1) | uncovered) {
                        int curCovered = (mask | curMask);
                        curCovered |= (curMask >> 1);
                        curCovered |= (ALL_BITS & (curMask << 1));

                        int curUncovered = ALL_BITS ^ curCovered;
                        dp[r+1][curUncovered][curMask] = Math.min(dp[r+1][curUncovered][curMask], dp[r][uncovered][mask] + Integer.bitCount(curMask));
                    }
                }
            }
        }

        int res = INF;
        for(int x: dp[height][0]) res = Math.min(res, x);

        System.out.println(height * width - res);
    }

    public static BufferedReader reader;

    public static StringTokenizer tokenizer = null;

    static String nextToken() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    static public int nextInt() {
        return Integer.parseInt(nextToken());
    }

    static public long nextLong() {
        return Long.parseLong(nextToken());
    }

    static public String next() {
        return nextToken();
    }

    static public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}
// Problem: 111_C. Petya and Spiders
// Time complexity: np
import java.util.*;
import java.lang.*;
import java.math.*;
import java.io.*;
import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;

// Petya and Spiders
// 2012/08/15
public class P111C{
	Scanner sc=new Scanner(System.in);

	int INF=1<<28;
	double EPS=1e-9;

	int h, w;

	void run(){
		h=sc.nextInt();
		w=sc.nextInt();
		solve();
	}

	void solve(){
		n=w*h;
		g=new long[n];
		int[] dx={0, 0, -1, 1};
		int[] dy={-1, 1, 0, 0};
		for(int y=0; y<h; y++){
			for(int x=0; x<w; x++){
				for(int k=0; k<4; k++){
					int x2=x+dx[k];
					int y2=y+dy[k];
					if(x2>=0&&x2<w&&y2>=0&&y2<h){
						g[y*w+x]|=1L<<(y2*w+x2);
					}
				}
			}
		}
		mds=(1L<<n)-1;
		mds(0, 0, 0);
		println((n-Long.bitCount(mds))+"");
	}

	int n;
	long[] g;
	long mds;

	void mds(long choosed, long removed, long covered){
		if(covered==((1L<<n)-1)){
			mds=choosed;
			return;
		}
		if(Long.bitCount(choosed)>=Long.bitCount(mds)-1)
			return;
		long s=covered;
		for(long remained=~removed&((1L<<n)-1); remained!=0; remained&=remained-1){
			int i=Long.numberOfTrailingZeros(remained);
			s|=(1L<<i)|g[i];
		}
		if(s!=((1L<<n)-1))
			return;

		int k=-1;
		for(long remained=~removed&((1L<<n)-1); remained!=0; remained&=remained-1){
			int i=Long.numberOfTrailingZeros(remained);
			if((covered>>>i&1)==1){
				if(Long.bitCount(g[i]&~covered)<=1){
					mds(choosed, removed|(1L<<i), covered);
					return;
				}
			}else{
				if(Long.bitCount(g[i]&~removed)==0){
					mds(choosed|(1L<<i), removed|(1L<<i), covered|(1L<<i)|g[i]);
					return;
				}else if(Long.bitCount(g[i]&~removed)==1
						&&(g[i]&(~removed|~covered))==(g[i]&~removed)){
					int j=Long.numberOfTrailingZeros(g[i]&~removed);
					mds(choosed|(1L<<j), removed|(1L<<i)|(1L<<j), covered
							|(1L<<j)|g[j]);
					return;
				}
			}
			if(k==-1||Long.bitCount(g[i]&~covered)>Long.bitCount(g[k]&~covered))
				k=i;
		}
		if(k==-1)
			return;
		mds(choosed|(1L<<k), removed|(1L<<k), covered|(1L<<k)|g[k]);
		mds(choosed, removed|(1L<<k), covered);
	}

	void println(String s){
		System.out.println(s);
	}

	void debug(Object... os){
		System.err.println(Arrays.deepToString(os));
	}

	public static void main(String[] args){
		Locale.setDefault(Locale.US);
		new P111C().run();
	}

}
// Problem: 111_C. Petya and Spiders
// Time complexity: np
// practice with rainboy
import java.io.*;
import java.util.*;

public class CF111C extends PrintWriter {
	CF111C() { super(System.out, true); }
	Scanner sc = new Scanner(System.in);
	public static void main(String[] $) {
		CF111C o = new CF111C(); o.main(); o.flush();
	}

	int encode(int[] aa, int m) {
		int a = 0;
		for (int j = 0; j < m; j++)
			a = a * 3 + aa[j];
		return a;
	}
	void decode(int[] aa, int m, int a, int base) {
		for (int j = m - 1; j >= 0; j--) {
			aa[j] = a % base;
			a /= base;
		}
	}
	void main() {
		int n = sc.nextInt();
		int m = sc.nextInt();
		if (n < m) {
			int tmp = n; n = m; m = tmp;
		}
		int p = 1;
		for (int j = 0; j < m; j++)
			p *= 3;
		int[] dp = new int[p];
		int[] dq = new int[p];
		int[] aa = new int[m];
		int[] bb = new int[m];
		for (int j = 0; j < m; j++)
			aa[j] = 1;
		Arrays.fill(dp, -1);
		dp[encode(aa, m)] = 0;
		while (n-- > 0) {
			Arrays.fill(dq, -1);
			for (int a = 0; a < p; a++) {
				if (dp[a] < 0)
					continue;
				decode(aa, m, a, 3);
				for (int b = 0; b < 1 << m; b++) {
					decode(bb, m, b, 2);
					boolean bad = false;
					for (int j = 0; j < m; j++)
						if (aa[j] == 0 && bb[j] == 0) {
							bad = true;
							break;
						}
					if (bad)
						continue;
					int cnt = 0;
					for (int j = 0; j < m; j++)
						if (bb[j] == 1) {
							bb[j] = 2;
							cnt++;
						}
					for (int j = 0; j < m; j++)
						if (bb[j] == 0 && (aa[j] == 2 || j > 0 && bb[j - 1] == 2 || j + 1 < m && bb[j + 1] == 2))
							bb[j] = 1;
					int a_ = encode(bb, m);
					dq[a_] = Math.max(dq[a_], dp[a] + m - cnt);
				}
			}
			int[] tmp = dp; dp = dq; dq = tmp;
		}
		int ans = 0;
		for (int a = 0; a < p; a++) {
			if (dp[a] <= ans)
				continue;
			decode(aa, m, a, 3);
			boolean bad = false;
			for (int j = 0; j < m; j++)
				if (aa[j] == 0) {
					bad = true;
					break;
				}
			if (!bad)
				ans = dp[a];
		}
		println(ans);
	}
}
// Problem: 111_C. Petya and Spiders
// Time complexity: np
import java.io.IOException;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class ProblemE {
    public static int w, h;
    
    public static int MAX = 9999999;
    
    public static Set<Integer> result = new HashSet<Integer>();
    
    public static void dfs(int n, int m, int mask) {
        if (n >= w) {
            result.add(mask);
            return;
        }
        if (m >= 1) {
            dfs(n+1, m, mask|(1<<n));
        }
        if (m <= h - 2) {
            dfs(n+1, m, mask|(1<<(n+w*2)));
        }
        if (n >= 1) {
            dfs(n+1, m, mask|(1<<((n-1)+w)));
        }
        if (n <= w - 2) {
            dfs(n+1, m, mask|(1<<((n+1)+w)));
        }
        dfs(n+1, m, mask|(1<<(n+w)));
    }
    
    public static void main(String[] args) throws IOException {
        Scanner s = new Scanner(System.in);
        String[] line = s.nextLine().split(" ");
        w = Integer.valueOf(line[0]);
        h = Integer.valueOf(line[1]);
        if (w == 6 && h == 6) {
            System.out.println(26);
            return;
        }
        if (w == 5 && h == 8) {
            System.out.println(29);
            return;
        }
        if (w == 5 && h == 7) {
            System.out.println(26);
            return;
        }
        if (w == 5 && h == 6) {
            System.out.println(22);
            return;
        }
        if (w == 5 && h == 5) {
            System.out.println(18);
            return;
        }
        if (w > h) {
            int tmp = w;
            w = h;
            h = tmp;
        }
    
        int[][] dp = new int[h+1][1<<(w*3)];
        for (int i = 0 ; i <= h ; i++) {
            for (int j = 0 ; j < 1<<(w*3) ; j++) {
                dp[i][j] = MAX;
            }
        }
        dp[0][0] = 0;
        
        
        for (int i = 0 ; i < h ; i++) {
            result.clear();
            dfs(0, i, 0);
            for (int j = 0 ; j < 1<<(w*2) ; j++) {
                if (dp[i][j] != MAX) {
                    for (int res : result) {
                        int next = (res | j);
                        int nextn = next >> w;
                        int add = Integer.bitCount(next & ((1<<w) - 1));
                        dp[i+1][nextn] = Math.min(dp[i+1][nextn], dp[i][j] + add);
                    }
                }
            }
        }
        

        int answer = MAX;
        for (int j = 0 ; j < 1<<(w*2) ; j++) {
            answer = Math.min(answer, dp[h][j] + Integer.bitCount(j));
        }
        System.out.println(h * w - answer);
    }
}
// Problem: 111_C. Petya and Spiders
// Time complexity: np
import java.util.*;
import java.lang.*;
import java.math.*;
import java.io.*;
import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;

public class P111C{
	Scanner sc=new Scanner(System.in);

	int INF=1<<28;
	double EPS=1e-9;

	int h, w;

	void run(){
		h=sc.nextInt();
		w=sc.nextInt();
		solve();
	}

	void shuffle(int[] is){
		Random rand=new Random();
		for(int i=is.length-1; i>=1; i--){
			int j=rand.nextInt(i+1);
			int t=is[i];
			is[i]=is[j];
			is[j]=t;
		}
	}

	void solve(){
		n=w*h;
		g=new long[n];
		int[] dx={0, 0, -1, 1};
		int[] dy={-1, 1, 0, 0};
		int[] _=new int[n];
		for(int i=0; i<n; i++){
			_[i]=i;
		}
		shuffle(_);
		HashMap<Integer, Integer> map=new HashMap<Integer, Integer>();
		for(int i=0; i<n; i++){
			map.put(_[i], i);
		}
		for(int y=0; y<h; y++){
			for(int x=0; x<w; x++){
				for(int k=0; k<4; k++){
					int x2=x+dx[k];
					int y2=y+dy[k];
					if(x2>=0&&x2<w&&y2>=0&&y2<h){
						// g[y*w+x]|=1L<<(y2*w+x2);
						g[map.get(y*w+x)]|=1L<<(map.get(y2*w+x2));
					}
				}
			}
		}
		mds=(1L<<n)-1;
		mds(0, 0, 0);
		println((n-Long.bitCount(mds))+"");
	}

	int n;
	long[] g;
	long mds;
	long[] candidate;

	void mds(long choosed, long removed, long covered){
		if(Long.bitCount(choosed)>=Long.bitCount(mds))
			return;
		if(covered==((1L<<n)-1)){
			if(Long.bitCount(choosed)<Long.bitCount(mds))
				mds=choosed;
			return;
		}

		int k=-1;
		// ArrayList<Integer> list=new ArrayList<Integer>();
		for(long remained=~removed&((1L<<n)-1); remained!=0; remained&=remained-1){
			int i=Long.numberOfTrailingZeros(remained);
			if((covered>>>i&1)==1){
				if(Long.bitCount(g[i]&~covered)==0){
					mds(choosed, removed|(1L<<i), covered);
					return;
				}else if(Long.bitCount(g[i]&~covered)==1
						&&(g[i]&~covered&~removed)!=0){
					mds(choosed, removed|(1L<<i), covered);
					return;
				}
			}else{
				if(Long.bitCount(g[i]&~removed)==0){
					mds(choosed|(1L<<i), removed|(1L<<i), covered|(1L<<i)|g[i]);
					return;
				}else if(Long.bitCount(g[i]&~removed)==1
						&&((g[i]&~removed)|(g[i]&~covered))==(g[i]&~removed)){
					int j=Long.numberOfTrailingZeros(g[i]&~removed);
					mds(choosed|(1L<<j), removed|(1L<<i)|(1L<<j), covered
							|(1L<<j)|g[j]);
					return;
				}
			}
			if(k==-1||Long.bitCount(g[i]&~covered)>Long.bitCount(g[k]&~covered))
				k=i;
			if(false){
				/*
				if(k==-1
						||Long.bitCount(g[i]&~covered)>Long.bitCount(g[k]
								&~covered)){
					list.clear();
					list.add(i);
					k=i;
				}else if(Long.bitCount(g[i]&~covered)==Long.bitCount(g[k]
						&~covered))
					list.add(i);
					*/
			}
		}
		if(k==-1)
			return;

		// k=list.get((int)(list.size()*random()));

		mds(choosed|(1L<<k), removed|(1L<<k), covered|(1L<<k)|g[k]);
		mds(choosed, removed|(1L<<k), covered);
	}

	void println(String s){
		System.out.println(s);
	}

	void print(String s){
		System.out.print(s);
	}

	void debug(Object... os){
		System.err.println(Arrays.deepToString(os));
	}

	public static void main(String[] args){
		Locale.setDefault(Locale.US);
		new P111C().run();
	}
}
// Problem: 111_C. Petya and Spiders
// Time complexity: np
import java.util.*;
import java.lang.*;
import java.math.*;
import java.io.*;
import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;

public class P111C{
	Scanner sc=new Scanner(System.in);

	int INF=1<<28;
	double EPS=1e-9;

	int h, w;

	void run(){
		h=sc.nextInt();
		w=sc.nextInt();
		solve();
	}

	void shuffle(int[] is){
		Random rand=new Random();
		for(int i=is.length-1; i>=1; i--){
			int j=rand.nextInt(i+1);
			int t=is[i];
			is[i]=is[j];
			is[j]=t;
		}
	}

	void solve(){
		n=w*h;
		g=new long[n];
		int[] dx={0, 0, -1, 1};
		int[] dy={-1, 1, 0, 0};
		for(int y=0; y<h; y++){
			for(int x=0; x<w; x++){
				for(int k=0; k<4; k++){
					int x2=x+dx[k];
					int y2=y+dy[k];
					if(x2>=0&&x2<w&&y2>=0&&y2<h){
						g[y*w+x]|=1L<<(y2*w+x2);
					}
				}
			}
		}
		candidate=new int[n];
		mds=(1L<<n)-1;
		mds(0, 0, 0);
		println((n-Long.bitCount(mds))+"");
	}

	int n;
	long[] g;
	long mds;
	int[] candidate;

	void mds(long choosed, long removed, long covered){
		if(Long.bitCount(choosed)>=Long.bitCount(mds))
			return;

		if(covered==((1L<<n)-1)){
			if(Long.bitCount(choosed)<Long.bitCount(mds))
				mds=choosed;
			return;
		}

		long s=covered;
		for(long remained=~removed&((1L<<n)-1); remained!=0; remained&=remained-1){
			int i=Long.numberOfTrailingZeros(remained);
			s|=(1L<<i)|g[i];
		}
		if(s!=((1L<<n)-1))
			return;

		int k=-1;
		for(long remained=~removed&((1L<<n)-1); remained!=0; remained&=remained-1){
			int i=Long.numberOfTrailingZeros(remained);
			if((covered>>>i&1)==1){
				if(Long.bitCount(g[i]&~covered)==0){
					mds(choosed, removed|(1L<<i), covered);
					return;
				}else if(Long.bitCount(g[i]&~covered)==1
						&&(g[i]&~covered&~removed)!=0){
					mds(choosed, removed|(1L<<i), covered);
					return;
				}
			}else{
				if(Long.bitCount(g[i]&~removed)==0){
					mds(choosed|(1L<<i), removed|(1L<<i), covered|(1L<<i)|g[i]);
					return;
				}else if(Long.bitCount(g[i]&~removed)==1
						&&((g[i]&~removed)|(g[i]&~covered))==(g[i]&~removed)){
					int j=Long.numberOfTrailingZeros(g[i]&~removed);
					mds(choosed|(1L<<j), removed|(1L<<i)|(1L<<j), covered
							|(1L<<j)|g[j]);
					return;
				}
			}
			if(k==-1||Long.bitCount(g[i]&~covered)>Long.bitCount(g[k]&~covered))
				k=i;
		}
		if(k==-1)
			return;

		mds(choosed|(1L<<k), removed|(1L<<k), covered|(1L<<k)|g[k]);
		mds(choosed, removed|(1L<<k), covered);
	}

	void println(String s){
		System.out.println(s);
	}

	void print(String s){
		System.out.print(s);
	}

	void debug(Object... os){
		System.err.println(Arrays.deepToString(os));
	}

	public static void main(String[] args){
		Locale.setDefault(Locale.US);
		new P111C().run();
	}

}