import sys



"""テンプレ"""



# 高速

input = sys.stdin.readline



# 1行を空白でリストにする(int)

def intline():

    return list(map(int, input().split()))





# 上のstrヴァージョン

def strline():

    return list(map(str, input().split()))





# 1列に並んだ数

def intlines(n):

    return [int(eval(input()) for _ in range(n))]





# 上の文字列ヴァージョン

def lines(n):

    return [eval(input()) for _ in range(n)]

    



"""ここからメインコード"""



a, b, _ = intline()

print((a * b // 2))
import sys



"""テンプレ"""



# 高速

input = sys.stdin.readline



# 1行を空白でリストにする(int)

def intline():

    return list(map(int, input().split()))





# 上のstrヴァージョン

def strline():

    return list(map(str, input().split()))





# 1列に並んだ数

def intlines(n):

    return [int(eval(input()) for _ in range(n))]





# 上の文字列ヴァージョン

def lines(n):

    return [eval(input()) for _ in range(n)]

    



# Union-Find木  http://at274.hatenablog.com/entry/2018/02/02/173000

class UnionFind:

    def __init__(self, n):

        self.par = [i for i in range(n+1)]

        self.rank = [0] * (n+1)



    # 検索

    def find(self, x):

        if self.par[x] == x:

            return x

        else:

            self.par[x] = self.find(self.par[x])

            return self.par[x]



    # 併合

    def union(self, x, y):

        x = self.find(x)

        y = self.find(y)

        if self.rank[x] < self.rank[y]:

            self.par[x] = y

        else:

            self.par[y] = x

            if self.rank[x] == self.rank[y]:

                self.rank[x] += 1



    # 同じ集合に属するか判定

    def same_check(self, x, y):

        return self.find(x) == self.find(y)





# 重み付きのUnion-Find木　http://at274.hatenablog.com/entry/2018/02/03/140504

class WeightedUnionFind:

    def __init__(self, n):

        self.par = [i for i in range(n+1)]

        self.rank = [0] * (n+1)

        # 根への距離を管理

        self.weight = [0] * (n+1)



    # 検索

    def find(self, x):

        if self.par[x] == x:

            return x

        else:

            y = self.find(self.par[x])

            # 親への重みを追加しながら根まで走査

            self.weight[x] += self.weight[self.par[x]]

            self.par[x] = y

            return y



    # 併合

    def union(self, x, y, w):

        rx = self.find(x)

        ry = self.find(y)

        # xの木の高さ < yの木の高さ

        if self.rank[rx] < self.rank[ry]:

            self.par[rx] = ry

            self.weight[rx] = w - self.weight[x] + self.weight[y]

        # xの木の高さ ≧ yの木の高さ

        else:

            self.par[ry] = rx

            self.weight[ry] = -w - self.weight[y] + self.weight[x]

            # 木の高さが同じだった場合の処理

            if self.rank[rx] == self.rank[ry]:

                self.rank[rx] += 1



    # 同じ集合に属するか

    def same(self, x, y):

        return self.find(x) == self.find(y)



    # xからyへのコスト

    def diff(self, x, y):

        return self.weight[x] - self.weight[y]









"""ここからメインコード"""





a, b, _ = intline()

print((a * b // 2))

import sys

"""テンプレ"""
# 高速
input = sys.stdin.readline
# 1行を空白でリストにする(int)
def intline():
    return list(map(int, input().split()))


# 上のstrヴァージョン
def strline():
    return list(map(str, input().split()))


# 1列に並んだ数
def intlines(n):
    return [int(eval(input()) for _ in range(n))]


# 上の文字列ヴァージョン
def lines(n):
    return [eval(input()) for _ in range(n)]


"""ここからメインコード"""
a, b, _ = intline()
print((a * b // 2))

import sys

"""テンプレ"""
# 高速
input = sys.stdin.readline
# 1行を空白でリストにする(int)
def intline():
    return list(map(int, input().split()))


# 上のstrヴァージョン
def strline():
    return list(map(str, input().split()))


# 1列に並んだ数
def intlines(n):
    return [int(eval(input()) for _ in range(n))]


# 上の文字列ヴァージョン
def lines(n):
    return [eval(input()) for _ in range(n)]


# Union-Find木  http://at274.hatenablog.com/entry/2018/02/02/173000
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n + 1)]
        self.rank = [0] * (n + 1)

    # 検索
    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    # 併合
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
        else:
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same_check(self, x, y):
        return self.find(x) == self.find(y)


# 重み付きのUnion-Find木　http://at274.hatenablog.com/entry/2018/02/03/140504
class WeightedUnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n + 1)]
        self.rank = [0] * (n + 1)
        # 根への距離を管理
        self.weight = [0] * (n + 1)

    # 検索
    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            y = self.find(self.par[x])
            # 親への重みを追加しながら根まで走査
            self.weight[x] += self.weight[self.par[x]]
            self.par[x] = y
            return y

    # 併合
    def union(self, x, y, w):
        rx = self.find(x)
        ry = self.find(y)
        # xの木の高さ < yの木の高さ
        if self.rank[rx] < self.rank[ry]:
            self.par[rx] = ry
            self.weight[rx] = w - self.weight[x] + self.weight[y]
        # xの木の高さ ≧ yの木の高さ
        else:
            self.par[ry] = rx
            self.weight[ry] = -w - self.weight[y] + self.weight[x]
            # 木の高さが同じだった場合の処理
            if self.rank[rx] == self.rank[ry]:
                self.rank[rx] += 1

    # 同じ集合に属するか
    def same(self, x, y):
        return self.find(x) == self.find(y)

    # xからyへのコスト
    def diff(self, x, y):
        return self.weight[x] - self.weight[y]


"""ここからメインコード"""
a, b, _ = intline()
print((a * b // 2))

+# Union-Find木  http://at274.hatenablog.com/entry/2018/02/02/173000 +class UnionFind: +    def __init__(self, n): +        self.par = [i for i in range(n + 1)] +        self.rank = [0] * (n + 1) + +    # 検索 +    def find(self, x): +        if self.par[x] == x: +            return x +        else: +            self.par[x] = self.find(self.par[x]) +            return self.par[x] + +    # 併合 +    def union(self, x, y): +        x = self.find(x) +        y = self.find(y) +        if self.rank[x] < self.rank[y]: +            self.par[x] = y +        else: +            self.par[y] = x +            if self.rank[x] == self.rank[y]: +                self.rank[x] += 1 + +    # 同じ集合に属するか判定 +    def same_check(self, x, y): +        return self.find(x) == self.find(y) + + +# 重み付きのUnion-Find木　http://at274.hatenablog.com/entry/2018/02/03/140504 +class WeightedUnionFind: +    def __init__(self, n): +        self.par = [i for i in range(n + 1)] +        self.rank = [0] * (n + 1) +        # 根への距離を管理 +        self.weight = [0] * (n + 1) + +    # 検索 +    def find(self, x): +        if self.par[x] == x: +            return x +        else: +            y = self.find(self.par[x]) +            # 親への重みを追加しながら根まで走査 +            self.weight[x] += self.weight[self.par[x]] +            self.par[x] = y +            return y + +    # 併合 +    def union(self, x, y, w): +        rx = self.find(x) +        ry = self.find(y) +        # xの木の高さ < yの木の高さ +        if self.rank[rx] < self.rank[ry]: +            self.par[rx] = ry +            self.weight[rx] = w - self.weight[x] + self.weight[y] +        # xの木の高さ ≧ yの木の高さ +        else: +            self.par[ry] = rx +            self.weight[ry] = -w - self.weight[y] + self.weight[x] +            # 木の高さが同じだった場合の処理 +            if self.rank[rx] == self.rank[ry]: +                self.rank[rx] += 1 + +    # 同じ集合に属するか +    def same(self, x, y): +        return self.find(x) == self.find(y) + +    # xからyへのコスト +    def diff(self, x, y): +        return self.weight[x] - self.weight[y] + +