///@author: suuuiii
//#pragma GCC target("avx2")
//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("O3")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

#define int128 __int128
#define int long long
#define ll long long
#define ld long double
#define ve vector
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define pb push_back
#define eb emplace_back
#define INF1 INT32_MAX
#define INF2 INT64_MAX
#define sz(x) (int)(x).size()


using namespace std;
using namespace __gnu_pbds;
random_device rd;
mt19937 rnd(rd());


int rand(int l, int r) {
    return l + rnd() % (r - l + 1);
}

template<typename key, typename cmp = less<key>>
using pbds = tree<key, null_type, cmp, rb_tree_tag, tree_order_statistics_node_update>;

const int Size = (1ll << 3), maxn = (int)1e5*2+1;

void solve() {
    int h, w; cin >> h >> w;

    deque<tuple<int, int, int>> q;

    if (h < w) swap(h, w);
    q.eb(h, w, 2);
    int ans = h*w;

    while (!q.empty()) {
        auto[n, m, c] = *q.begin();
        q.erase(q.begin());
        if (n==1) continue;

        if (n%2==0) {
            n /= 2;
            ans += n*m*c;
            if (n < m) swap(n, m);
            q.eb(n, m, c*2);
        }
        else {
            if (m%2==0) {
                m /= 2;
                ans += n*m*c;
                if (n < m) swap(n, m);
                q.eb(n, m, c*2);
            }
            else {
                n /= 2;
                ans += n*m*c/2;
                if (n < m) swap(n, m);
                q.eb(n, m, c);

                ++n;
                ans += n*m*c/2;
                if (n < m) swap(n, m);
                q.eb(n, m, c);
            }
        }
    }
    cout << ans;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int tt = 1;
//    cin >> tt;
    while (tt--){
        solve();
    }
}