#include using namespace std; #include using namespace atcoder; using ll = int64_t; using ul = uint64_t; using ld = long double; using vi = vector; using vd = vector; using vc = vector; using vs = vector; using vb = vector; using vl = vector; using vvi = vector; using vvd = vector; using vvc = vector; using vvb = vector; using vvl = vector; using mint = modint998244353; using vm = vector; // エラトステネスの篩みたいにやるのか void sieve(int N, vb &del) { for (int p = 2; p*p <= N; p++) { if (del[p]) continue; for (int a = p*p; a <= N; a += p) { del[a] = true; } } return; } int main() { int N,M; cin >> N >> M; ll mod = 998244353; vb del(N + 1, false); sieve(N, del); vi mu(N + 1, 1); for (int a = 2; a <= N; a++) { if (del[a]) continue; for (int b = 1; a*b <= N; b++) { if (b%a == 0) mu[a*b] = 0; else mu[a*b] *= -1; } } ll ans = 0; for (ll d = 1; d <= min(N, M); d++) { ll n = N/d,m = M/d; n = (n + 1)*n/2,m = (m + 1)*m/2; n *= d,m *= d; n %= mod,m %= mod; ans += mu[d]*n*m%mod; ans %= mod; } cout << ans << endl; return 0; }