#include <bits/stdc++.h>
using namespace std;

#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define ALL(a) begin(a), end(a)
#define SZ(a) ((int)(a).size())

#define REP(a, b) for (int a = 0; a < (b); a++)
#define FOR(a, b, c) for (int a = (b); a <= (c); a++)
#define REPD(a, b) for (int a = (b) - 1; a >= 0; a--)
#define FORD(a, b, c) for (int a = (b); a >= (c); a--)

#define MIN(a, b) (a) = min((a), (b))
#define MAX(a, b) (a) = max((a), (b))

#if defined(__GNUC__)
#define LIKELY(x) (__builtin_expect((x), 1))
#define UNLIKELY(x) (__builtin_expect((x), 0))
#else
#define LIKELY(x) (x)
#define UNLIKELY(x) (x)
#endif  // defined(__GNUC__)

#ifdef __DEBUG
#define debug if (true)
#else
#define debug if (false)
#endif  // __DEBUG

template <typename... T>
using tpl = tuple<T...>;

#define DECLARE_TUPLE_ACCESSOR(TIDX) \
  struct TupleIndex_##TIDX##_t {};\
  template <typename... T>\
  typename tuple_element<TIDX, tuple<T...>>::type& operator/(tuple<T...>& t, TupleIndex_##TIDX##_t) { return get<TIDX>(t); }\
  template <typename... T>\
  const typename tuple_element<TIDX, tuple<T...>>::type& operator/(const tuple<T...>& t, TupleIndex_##TIDX##_t) { return get<TIDX>(t); }\
  constexpr TupleIndex_##TIDX##_t _##TIDX;

DECLARE_TUPLE_ACCESSOR(0)
DECLARE_TUPLE_ACCESSOR(1)
DECLARE_TUPLE_ACCESSOR(2)
DECLARE_TUPLE_ACCESSOR(3)

#undef DECLARE_TUPLE_ACCESSOR

using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;

template <typename T> using V = vector<T>;
template <typename T> using VV = vector<V<T>>;
template <typename T> using VVV = vector<VV<T>>;

template <typename T1, typename T2>
istream& operator>>(istream& is, pair<T1, T2> &p) {
  return is >> p.fi >> p.se;
}

#if __cplusplus > 201402L
template <typename... T, size_t... I>
istream& tupleInputImpl(istream &is, tuple<T...> &tpl, index_sequence<I...>) {
  return (is >> ... >> get<I>(tpl));
}

template <typename... T>
istream& operator>>(istream& is, tuple<T...> &tpl) {
  return tupleInputImpl(is, tpl, index_sequence_for<T...>{});
}
#endif  // __cplusplus > 201402L

const int MX = 1e6 + 6;
const int MOD = 998244353;

int add(int a, int b) { if ((a += b) >= MOD) a -= MOD; return a; }
int mul(int a, int b) { return 1LL * a * b % MOD; }

int pw(int a, int p) {
  int res = 1;
  while (p > 0) {
    if (p & 1) res = mul(res, a);
    p >>= 1;
    a = mul(a, a);
  }
  return res;
}

int inv(int a) {
  return pw(a, MOD - 2);
}

int pre[MX];
int c[MX];

void Main() {
  FOR(i, 1, MX - 1) pre[i] = inv(i);
  FOR(i, 1, MX - 1) {
    for (int j = i + i; j < MX; j += i) pre[j] = add(pre[j], MOD - pre[i]);
  }
  int n;
  cin >> n;
  REP(i, n) {
    int x;
    cin >> x;
    c[x]++;
  }
  int ans = 0;
  FOR(i, 1, MX - 1) {
    int cur = 0;
    for (int j = i; j < MX; j += i) {
      cur = add(cur, mul(c[j], j));
    }
    ans = add(ans, mul(pre[i], mul(cur, cur)));
  }
  FOR(i, 1, MX - 1) if (c[i] > 0) ans = add(ans, MOD - mul(c[i], i));
  if (ans % 2 == 1) ans += MOD;
  ans /= 2;
  cout << ans << endl;
}

int main(int argc, char *argv[]) {
  if (argc > 1) {
    freopen(argv[1], "r", stdin);
  } else {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
  }
  Main();
}


Measured memory_bytes: 8064