Problem:
Score : 200 points

Problem Statement

We have a board with H horizontal rows and W vertical columns of squares.
There is a bishop at the top-left square on this board.
How many squares can this bishop reach by zero or more movements?

Here the bishop can only move diagonally.
More formally, the bishop can move from the square at the r_1-th row (from the top) and the c_1-th column (from the left) to the square at the r_2-th row and the c_2-th column if and only if exactly one of the following holds:

r_1 + c_1 = r_2 + c_2

r_1 - c_1 = r_2 - c_2

For example, in the following figure, the bishop can move to any of the red squares in one move:

Constraints

1 \leq H, W \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

H \ W

Output

Print the number of squares the bishop can reach.

Sample Input 1

4 5

Sample Output 1

10

The bishop can reach the cyan squares in the following figure:

Sample Input 2

7 3

Sample Output 2

11

The bishop can reach the cyan squares in the following figure:

Sample Input 3

1000000000 1000000000

Sample Output 3

500000000000000000

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text;
using System.Linq;

using E = System.Linq.Enumerable;

internal partial class Solver {
    public void Run() {
        var h = nl();
        var w = nl();
        if (w == 1 || h == 1) {
            cout.WriteLine(1);
        } else {
            long ans = (h - h / 2) * (w - w / 2) + (h / 2) * (w / 2);
            cout.WriteLine(ans);
        }
    }
}

// PREWRITEN CODE BEGINS FROM HERE
internal partial class Solver : Scanner {
    public static void Main(string[] args) {
#if LOCAL
        byte[] inputBuffer = new byte[1000000];
        var inputStream = Console.OpenStandardInput(inputBuffer.Length);
        using (var reader = new StreamReader(inputStream, Console.InputEncoding, false, inputBuffer.Length)) {
            Console.SetIn(reader);
            new Solver(Console.In, Console.Out).Run();
        }
#else
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()){ AutoFlush = false });
        new Solver(Console.In, Console.Out).Run();
        Console.Out.Flush();
#endif
    }

#pragma warning disable IDE0052
    private readonly TextReader cin;
    private readonly TextWriter cout;
#pragma warning restore IDE0052

    public Solver(TextReader reader, TextWriter writer)
        : base(reader) {
        cin = reader;
        cout = writer;
    }
    public Solver(string input, TextWriter writer)
        : this(new StringReader(input), writer) {
    }

#pragma warning disable IDE1006
#pragma warning disable IDE0051
    private int ni() { return NextInt(); }
    private int[] ni(int n) { return NextIntArray(n); }
    private long nl() { return NextLong(); }
    private long[] nl(int n) { return NextLongArray(n); }
    private double nd() { return NextDouble(); }
    private double[] nd(int n) { return NextDoubleArray(n); }
    private string ns() { return Next(); }
    private string[] ns(int n) { return NextArray(n); }
#pragma warning restore IDE1006
#pragma warning restore IDE0051
}

internal static class LinqPadExtension {
    [Conditional("DEBUG")]
    public static void Dump<T>(this T obj) {
#if DEBUG
        LINQPad.Extensions.Dump(obj);
#endif
    }
}

public class Scanner {
    private readonly TextReader Reader;
    private readonly CultureInfo ci = CultureInfo.InvariantCulture;

    private readonly char[] buffer = new char[2 * 1024];
    private int cursor = 0, length = 0;
    private string Token;
    private readonly StringBuilder sb = new StringBuilder(1024);

    public Scanner()
        : this(Console.In) {
    }

    public Scanner(TextReader reader) {
        Reader = reader;
    }

    public int NextInt() { return checked((int)NextLong()); }
    public long NextLong() {
        var s = Next();
        long r = 0;
        int i = 0;
        bool negative = false;
        if (s[i] == '-') {
            negative = true;
            i++;
        }
        for (; i < s.Length; i++) {
            r = r * 10 + (s[i] - '0');
#if DEBUG
            if (!char.IsDigit(s[i])) throw new FormatException();
#endif
        }
        return negative ? -r : r;
    }
    public double NextDouble() { return double.Parse(Next(), ci); }
    public string[] NextArray(int size) {
        string[] array = new string[size];
        for (int i = 0; i < size; i++) {
            array[i] = Next();
        }

        return array;
    }
    public int[] NextIntArray(int size) {
        int[] array = new int[size];
        for (int i = 0; i < size; i++) {
            array[i] = NextInt();
        }

        return array;
    }

    public long[] NextLongArray(int size) {
        long[] array = new long[size];
        for (int i = 0; i < size; i++) {
            array[i] = NextLong();
        }

        return array;
    }

    public double[] NextDoubleArray(int size) {
        double[] array = new double[size];
        for (int i = 0; i < size; i++) {
            array[i] = NextDouble();
        }

        return array;
    }

    public string Next() {
        if (Token == null) {
            if (!StockToken()) {
                throw new InvalidOperationException();
            }
        }
        var token = Token;
        Token = null;
        return token;
    }

    public bool HasNext() {
        if (Token != null) {
            return true;
        }

        return StockToken();
    }

    private bool StockToken() {
        while (true) {
            sb.Clear();
            while (true) {
                if (cursor >= length) {
                    cursor = 0;
                    if ((length = Reader.Read(buffer, 0, buffer.Length)) <= 0) {
                        break;
                    }
                }
                var c = buffer[cursor++];
                if (33 <= c && c <= 126) {
                    sb.Append(c);
                } else {
                    if (sb.Length > 0) break;
                }
            }

            if (sb.Length > 0) {
                Token = sb.ToString();
                return true;
            }

            return false;
        }
    }
}