int n, mx; int64_t ans; int a[kMaxN], mu[kMaxN], s[kMaxN]; bool exi[kMaxN]; std::vector<int> d[kMaxN];
voidprework(int n = mx){ staticint prime[kMaxN]; staticbool vis[kMaxN]; for (int i = 1; i <= n; ++i) for (int j = i; j <= n; j += i) d[j].emplace_back(i); int m = 0; mu[1] = 1; for (int i = 2; i <= n; ++i) { if (!vis[i]) { mu[i] = -1, prime[++m] = i; } for (int j = 1; j <= m && i * prime[j] <= n; ++j) { int x = i * prime[j]; vis[x] = 1; if (i % prime[j]) mu[x] = -mu[i]; elsebreak; } } }
voidupd(int x, int v){ for (auto i : d[x]) s[i] += v * mu[i]; }
intget(int x){ int ret = 0; for (auto i : d[x]) ret += s[i]; return ret; }
voiddickdreamer(){ std::cin >> n; for (int i = 1; i <= n; ++i) { std::cin >> a[i]; mx = std::max(mx, a[i]); if (exi[a[i]]) ans = std::max<int64_t>(ans, a[i]); exi[a[i]] = 1; } prework(); for (int i = mx; i; --i) for (int j = 2 * i; j <= mx; j += i) exi[i] |= exi[j]; staticint stk[kMaxN]; int top = 0; for (int i = mx; i; --i) { if (!exi[i]) continue; if (get(i)) { while (true) { for (; top && std::__gcd(i, stk[top]) != 1; --top) upd(stk[top], -1); assert(top); ans = std::max<int64_t>(ans, 1ll * i * stk[top]); upd(stk[top], -1); if (get(i)) { --top; } else { upd(stk[top], 1); break; } } } stk[++top] = i, upd(i, 1); } std::cout << ans << '\n'; }