#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <deque>
#include <numeric>
#include <iomanip>

#ifndef Debug
#pragma GCC optimize("O3")
#endif

using ll = long long;

struct St {
    std::vector<ll> a, t;

    St(ll n) {
        a.resize(n, 1e9);
        t.resize(4 * n, 1e9);
    }

    void upd(ll v, ll l, ll r, ll i, ll nw) {
        if (l == r + 1) {
            t[v] = nw;
            return;
        }
        ll m = (l + r) / 2;
        if (i < m) {
            upd(2 * v + 1, l, m, i, nw);
        } else {
            upd(2 * v + 2, m, r, i, nw);
        }
        t[v] = std::min(t[2 * v + 1], t[2 * v + 2]);
    }

    ll get(ll v, ll l, ll r, ll ql, ll qr) {
        if (l >= qr || r <= ql) {
            return 1e9;
        }
        if (l <= ql && qr <= r) {
            return t[v];
        }
        ll m = (l + r) / 2;
        return std::min(get(2 * v + 1, l, m, ql, qr),
                        get(2 * v + 2, m, r, ql, qr));
    }
};

void bipkos() {
    ll h, w;
    std::cin >> h >> w;
    if (h == w && h == 1) {
        std::cout << 1;
        return;
    }
    ll ans1 = h * w, ans2 = h * w, cnt1 = (w * (w + 1)) / 2 - 1, cnt2 = (h * (h + 1)) / 2 - 1;
    ans1 += h * cnt1;
    ans2 += w * cnt2;
    ans1 += cnt2 * w;
    ans2 += cnt1 * h;
    std::cout << std::max(ans1, ans2);
    /*
     * ll ans1 = h * w, ans2 = h * w, cnt1 = (w * (w + 1)) / 2 - 1, cnt2 = (h * (h + 1)) / 2 - 1;
    ans1 += h * cnt1;
    ans2 += w * cnt2;
    bool flag1 = true, flag2 = true;
    if (h == 1) flag1 = false;
    if (w == 1) flag2 = false;
    for (ll i = 1; i < 25; i++) {
        ll kv = (1ll << i);
        if (h == kv) flag1 = false;
        if (w == kv) flag2 = false;
        ans1 += kv * w * (ll)(h / kv);
        ans2 += kv * h * (ll)(w / kv);
    }
    std::cout << std::max({ans1 + flag1 * h * w, ans2 + flag2 * h * w});
     */
    /*ll n;
    std::cin >> n;
    std::vector<ll> a(n);
    std::vector<ll> x;
    for (int i = 0; i < n; ++i) {
        std::cin >> a[i];
        x.push_back(a[i]);
    }
    std::sort(x.begin(), x.end());
    for (int i = 0; i < n; ++i) {
        a[i] = std::lower_bound(x.begin(), x.end(), a[i]) - x.begin();
    }
    std::vector<ll> dp(n);
    St b(n);
    ll maxx = 0;
    for (int i = 0; i < n; ++i) {
        ll cnt = 0, cnt1 = 0;
        ll xx = b.get(0, 0, n, a[i], n);
        b.upd(0, 0, n, a[i], a[i] + ((i == 0) ? 0 : dp[i - 1]));
        if(xx != 1e9){
            cnt1 += xx;
        }
        cnt1 += a[i];
        dp[i] = std::max(cnt1, cnt);
    }*/
}

int main() {
    std::cin.tie(nullptr), std::ios::sync_with_stdio(false);
    int t = 1;
//    std::cin >> t;
    while (t--) {
        bipkos();
    }
}
