#include using ll = long long; constexpr ll P = 998244353; constexpr int MaxN = 2e5L; struct FenwickTree { static constexpr int IndexOffset = 2; static int Lowbit(int x) { return x&(-x); } std::vector b; FenwickTree() { b = std::vector(MaxN + 1 + IndexOffset); } void Reset() { fill(b.begin(), b.end(), 0); } void Add(int p, ll x) { p += IndexOffset; for(; p <= MaxN + IndexOffset; p += Lowbit(p)) { b[p] += x; } } ll Query(int p) { p += IndexOffset; ll r = 0; for(; p; p -= Lowbit(p)) { r += b[p]; } return r; } }; // sum of a_i ll Solve1(int n, std::vector a, std::vector orig_a) { ll r = 0; FenwickTree tree_cnt, tree_sum; for(int i = n - 1; i >= 0; i --) { ll cnt = tree_cnt.Query(a[i] - 1); ll sum = tree_sum.Query(a[i] - 1); r += ll(orig_a[i]) * (sum % P) % P; tree_cnt.Add(a[i], 1); tree_sum.Add(a[i], cnt); } return r % P; } // sum of a_j ll Solve2(int n, std::vector a, std::vector orig_a) { FenwickTree tree; std::vector cnt_lu(n), cnt_rd(n); for(int i = 0; i < n; i ++) { cnt_lu[i] = tree.Query(MaxN) - tree.Query(a[i]); tree.Add(a[i], 1); } tree.Reset(); for(int i = n - 1; i >= 0; i --) { cnt_rd[i] = tree.Query(a[i] - 1); tree.Add(a[i], 1); } ll r = 0; for(int i = 0; i < n; i ++) { r += ll(orig_a[i]) * cnt_lu[i] % P * cnt_rd[i] % P; } return r % P; } // sum of a_k ll Solve3(int n, std::vector a, std::vector orig_a) { reverse(a.begin(), a.end()); reverse(orig_a.begin(), orig_a.end()); for(int &x : a) { x = n - x; } return Solve1(n, a, orig_a); } std::vector Descretizate(std::vector v) { std::map f; for(int x : v) { f[x] = 0; } int cnt = 0; for(auto &[k, v] : f) { v = cnt ++; } std::vector u = v; for(int &x : u) { x = f[x]; } return u; } int main() { std::ios::sync_with_stdio(0); int n; std::cin >> n; std::vector a(n); for(int i = 0; i < n; i ++) { std::cin >> a[i]; } std::vector des_a = Descretizate(a); std::cout << (Solve1(n, des_a, a) + Solve2(n, des_a, a) + Solve3(n, des_a, a)) % P << '\n'; }