#include <iostream>
#include <vector>
#include <array>
#include <list>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <string>
#include <sstream>
#include <algorithm>
#include <random>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cmath>
#include <cassert>
#include <climits>
#include <bitset>
#include <functional>

#define FOR_LT(i, beg, end) for (int i = beg; i < end; i++)
#define FOR_LE(i, beg, end) for (int i = beg; i <= end; i++)
#define FOR_DW(i, beg, end) for (int i = beg; end <= i; i--)

using namespace std;

class Rational;
ostream & operator << (ostream & s, const Rational val);

class Rational {
public:
	Rational() : num_(0), denom_(1) {}

	Rational(int64_t num, int64_t denom)
		: num_(num), denom_(denom)
	{
		this->reduce();
	}

	Rational(int64_t num) : num_(num), denom_(1) {}

	Rational(const Rational& obj) : num_(obj.num_), denom_(obj.denom_) {}

	int64_t num() const { return this->num_; }
	int64_t denom() const { return this->denom_; }

	Rational operator+(const Rational& op) {
		int64_t denom = this->denom_ * op.denom_;
		int64_t num = this->num_ * op.denom_ + op.num_ * this->denom_;
		return Rational(num, denom);
	}

	Rational operator-(const Rational& op) {
		int64_t denom = this->denom_ * op.denom_;
		int64_t num = this->num_ * op.denom_ - op.num_ * this->denom_;
		return Rational(num, denom);
	}

	Rational operator*(const Rational& op) {
		int64_t denom = this->denom_ * op.denom_;
		int64_t num = this->num_ * op.num_;
		return Rational(num, denom);
	}

	Rational operator/(const Rational& op) {
		int64_t denom = this->denom_ * op.num_;
		int64_t num = this->num_ * op.denom_;
		return Rational(num, denom);
	}

	bool operator==(const Rational& op) {
		return (this->num_ == op.num_ && this->denom_ == op.denom_);
	}

private:

	void reduce() {
		if (this->num_ == 0) {
			this->denom_ = 1;
			return;
		}

		int64_t g = gcm(abs(this->num_), this->denom_);
		this->num_ /= g;
		this->denom_ /= g;
	}

	int64_t gcm(int64_t a, int64_t b) {
		if (a > b) swap(a, b);
		if (b % a == 0) return a;
		return gcm(b % a, a);
	}

	int64_t num_;
	int64_t denom_;
};

ostream& operator << (ostream & s, const Rational val) {
	s << val.num() << "/" << val.denom();
	return s;
}

static const int64_t kMax = 1000000;
static const int64_t kRem = 998244353;
//static int64_t kMax = 100;

static vector<Rational> ds = vector<Rational>(kMax + 1, Rational(1));

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int n; cin >> n;
	vector<int> vals(n); for (auto& v : vals) { cin >> v; }


	vector<int64_t> counts(kMax + 1);
	FOR_LT(i, 0, n) {
		counts[vals[i]]++;
	}

	FOR_LE(i, 2, kMax) {
		ds[i] = Rational(1, i) - ds[i];
		
		int v = i;
		bool has_value = false;
		while (v <= kMax) {
			if (counts[v] != 0) {
				has_value = true;
				break;
			}
			v += i;
		}

		if (!has_value) continue;

		v = i * 2;
		while (v <= kMax) {
			ds[v] = ds[v] + ds[i];
			v += i;
		}
	}

	int64_t ans(0);
	FOR_LE(i, 1, kMax) {
		int64_t v = 0;
		int64_t m = 0;
		for (int64_t j = i; j <= kMax; j += i) {
			if (counts[j] == 0) continue;

			v += ((m * j / i) % kRem) * counts[j];
			v %= kRem;
			v += ((j * j / i) % kRem) * ((counts[j] * (counts[j] - 1) / 2) % kRem);
			v %= kRem;
			m += j * counts[j];
			m %= kRem;
		}

		if (v == 0) continue;

		ans += (v * ds[i].num() % kRem) * (i / ds[i].denom());
		ans %= kRem;
		if (ans < 0) ans += kRem;
	}

	cout << ans << endl;

	return 0;
}

Measured memory_bytes: 24448