voidsieve(int n) { phi[1] = mu[1] = 1; for (int i = 2; i <= n; ++ i) { if (!st[i]) prime[++ cnt] = i, phi[i] = i - 1, mu[i] = -1; for (int j = 1; j <= cnt && i * prime[j] <= n; ++ j) { st[i * prime[j]] = true; if (i % prime[j] == 0) { phi[i * prime[j]] = phi[i] * prime[j]; break; } phi[i * prime[j]] = phi[i] * (prime[j] - 1); mu[i * prime[j]] = -mu[i]; } } for (int i = 1; i <= n; ++ i) adj(mu[i]), invphi[i] = qpow(phi[i]); for (int i = 1; i <= n; ++ i) for (int d = 1; d * i <= n; ++ d) g[i * d] = (g[i * d] + (LL) d * invphi[d] % Mod * mu[i]) % Mod; int cnt = 0; for (int T = 1; T <= n; ++ T) { f[T].push_back(0); for (int i = 1, tmp; i * T <= n; ++ i) f[T].push_back(adj(tmp = f[T].back() + phi[i * T] - Mod)); cnt += f[T].size(); } for (int s1 = 1; s1 <= B; ++ s1) for (int s2 = 1; s2 <= B; ++ s2) { auto &v = S[s1][s2]; v.push_back(0); for (int i = 1, ed = std::min(n / s1, n / s2); i <= ed; ++ i) v.push_back((v.back() + (LL) f[i][s1] * f[i][s2] % Mod * g[i]) % Mod); cnt += v.size(); } std::cerr << (cnt * 4 + std::abs(&mem1 - &mem2)) / 1048576. << " MB\n"; }
voidwork() { int n, m, res = 0; scanf("%d %d", &n, &m); if (n > m) std::swap(n, m); for (int i = 1; i <= m / B; ++ i) res = (res + (LL) g[i] * f[i][n / i] % Mod * f[i][m / i]) % Mod; for (int l = m / B + 1, r, tn, tm; l <= n; l = r + 1) { r = std::min(n / (tn = n / l), m / (tm = m / l)); adj(adj(res += S[tn][tm][r] - Mod) -= S[tn][tm][l - 1]); } printf("%d\n", res); }
intmain() { sieve(1e5 + 1); int T; std::cin >> T; while (T --) work(); return0; }