#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
using namespace __gnu_pbds;
using namespace std;
#define IO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define PI 3.1415926535897932384626433832795
#define endl "\n"
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
long long MOD = 998244353;
pair<int,int> dx[4] = {{1,0},{-1,0},{0,1},{0,-1}};
const int RANDOM = chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
struct chash {int operator()(int x) const { return x ^ RANDOM; }};
string toString(long long x){stringstream ss;ss << x;string str = ss.str();return str;}
long long fastpow(long long x,long long k){if(!k)return 1;if(k & 1)return ((x * fastpow(x,k-1) % MOD) % MOD) % MOD;
long long ans = fastpow(x,k/2);ans %= MOD;ans *= ans;ans %= MOD;return ans;}
long long sumF(long long x){int s = 0;while(x)s += x%10,x /= 10;return s;}
bool isS(char c){return (c >= 'a' && c <= 'z');}
bool isB(char c){return (c >= 'A' && c <= 'Z');}
bool isD(char c){return (c >= '0' && c <= '9');}
bool isSqrt(long long x){ long long f = sqrt((long double)x + 0.5); return f*f == x;}
bool isCubic(long long x) {long long f = cbrt((long double)x + 0.5); return f*f*f == x;}
long long lcm(long long a,long long b){return a * (b / __gcd(a,b));}
vector<long long> divVec(long long x){vector<long long> tmp;for(long long i = 1;1LL*i*i <= x;i++){if(x % i == 0){tmp.push_back(i);if(x / i != i)
tmp.push_back(x / i);}sort(tmp.begin(),tmp.end());}return tmp;}
int random_int(int l,int r){return uniform_int_distribution<int>(l,r)(rng);}
int primeFactorsCnt(long long n){int ret = 0;if(n % 2 == 0)ret++;while (n % 2 == 0)n = n/2;for (int i = 3; i*i <= n; i = i + 2){if(n % i == 0)ret++;while (n % i == 0)
n = n/i;}if (n > 2)ret++;return ret;}
long long mulmod(long long a,long long b)
{
    return ((a % MOD) * (b % MOD)) % MOD;
}
long long minusmod(long long a,long long b)
{
    return ((((a - b)) % MOD) + MOD) % MOD;
}
long long plusmod(long long a,long long b)
{
    return (a + b) % MOD;
}
long long freq[1000005];
int arr[200005];
long long dp[1000005];
long long invModulo[1000005];
void modularInverse(int n)
{
    invModulo[0] = invModulo[1] = 1;
    for (int i = 2; i <= n; i++)
        invModulo[i] = invModulo[MOD % i] *
               (MOD - MOD / i) % MOD;

}
long long solve(int n)
{
    int MX_element = 0;
    for(int i = 0;i < n;i++)
    {
        cin >> arr[i];
        //arr[i] = random_int(1,1e6);
        MX_element = max(MX_element,arr[i]);
        freq[arr[i]]++;
    }
    modularInverse(MX_element);
    long long ans = 0;
    for(int i = MX_element;i >= 1;i--)
    {
        long long c = mulmod(i,freq[i]);
        long long c2 = mulmod(i,mulmod(i,freq[i]));
        for(int j = i*2;j <= MX_element;j += i)
        {
            c = plusmod(c,mulmod(j,freq[j]));
            c2 = plusmod(c2,mulmod(j,mulmod(j,freq[j])));
            dp[i] = minusmod(dp[i],dp[j]);
        }
        dp[i] = plusmod(dp[i],minusmod(mulmod(c,c),c2));
        ans = plusmod(ans,mulmod(dp[i],invModulo[i]));
    }
    return ans;
}
int32_t main() {
    //freopen("lcm.in","r",stdin);
    IO;
    int t = 1;
    while(t--)
    {
        int n;
        cin >> n;
       // n = 2e5;
        cout << mulmod(solve(n),fastpow(2,MOD-2)) << endl;
    }

}


Measured memory_bytes: 24576