//  [typescript]
import * as fs from "fs"

class HashSet<T extends { [key: string]: number; }> implements Set<T> {
    set: Set<T> = new Set<T>()
    size: number = 0

    add = (value: T): this => {
        const keys = Object.keys(value)
        // 同一性チェック
        const array = this.toArray(this.set)
        const sameList = array.filter(e => {
            // 一致する長さがKeysの長さと一致
            return keys.filter(key => e[key] === value[key]).length === keys.length
        })
        if (sameList.length === 0) {
            this.set.add(value)
        }
        this.size = this.set.size
        return this
    }

    clear(): void {
        this.set = new Set<T>()
    }

    delete(value: T): boolean {
        throw new Error("Method not implemented.");
    }

    forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: any): void {
        this.set.forEach(callbackfn, thisArg)
    }

    has(value: T): boolean {
        const keys = Object.keys(value)
        return this.toArray(this.set).filter(e => e.x === value.x && e.y === value.y).length === keys.length
    }

    [Symbol.iterator](): IterableIterator<T> {
        throw new Error("Method not implemented.");
    }

    entries(): IterableIterator<[T, T]> {
        throw new Error("Method not implemented.");
    }

    keys(): IterableIterator<T> {
        throw new Error("Method not implemented.");
    }

    values(): IterableIterator<T> {
        throw new Error("Method not implemented.");
    }

    [Symbol.toStringTag]: string;

    toArray = (set: Set<T>): Array<T> => {
        const array = new Array<T>()
        const ite = set.values()
        let next = ite.next()
        while (!next.done) {
            array.push(next.value)
            next = ite.next()
        }
        return array
    }
}

function Main(input: any) {
    const inputs = input.split(' ')
    const H = inputs[0] as number
    const W = inputs[1] as number
    // console.log(`H:${H},W:${W}`)
    if (H < 2 || W < 2) {
        console.log(1);
        return
    }

    // // 座標リスト
    // const createExistsList = (H: number, W: number) => {
    //     let list = new Array<{ x: number, y: number }>()
    //     for (let x = 1; x <= H; x++) {
    //         for (let y = 1; y <= W; y++) {
    //             list.push({x: x, y: y})
    //         }
    //     }
    //     return list
    // }
    // const existsList = createExistsList(H, W)
    // 移動済みセット
    let calculated = new HashSet<{ x: number, y: number }>()
    // 座標を元に{x+1, y+1}, {X+1,y-1}, {x-1, y-1}, {x-1, y+1}を行う。
    const calcMovaleArray = (x: number, y: number): Array<{ x: number, y: number }> => {
        const targets = [{x: x + 1, y: y + 1}, {x: x + 1, y: y - 1}, {x: x - 1, y: y - 1}, {x: x - 1, y: y + 1}]
        return targets.filter(target => {
                let ret = false
                if ((target.x <= H && target.y <= W)
                    && (target.x > 0 && target.y > 0)) {
                    const r1plusc1 = x + y
                    const r1minusc1 = x - y
                    const r2plusc2 = target.x + target.y
                    const r2minusc2 = target.x - target.y

                    ret = r1plusc1 === r2plusc2 || r1minusc1 === r2minusc2
                }
                return ret
            }
        )
    }

    calculated.add({x: 1, y: 1})
    let beforeSize = 0

    let nextSet = calculated
    while (beforeSize !== calculated.size) {
        beforeSize = calculated.size
        let newSet = new HashSet<{ x: number, y: number }>()
        nextSet.forEach(zahyo => {
            calcMovaleArray(zahyo.x, zahyo.y).forEach(newSet.add)
        })
        // 計算済みへ追加
        newSet.forEach(e => calculated.add(e))
        // 次のセットへ設定
        nextSet = newSet
        // console.log(`size beforeSize:${beforeSize}, afterSize:${movedSet.size}`)
    }

    console.log(calculated.size)
}

Main(fs.readFileSync("/dev/stdin", "utf8"));