#include using namespace std; #include using namespace atcoder; using mint = atcoder::modint998244353; // using mint = double; #define rep(i, l, r) for (int i = (int)(l); i<(int)(r); i++) #define ll long long #define ld long double #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define siz(x) (int)(x).size() template bool chmin(T& a, T b) { if (a > b) {a = b; return true;} return false; } template bool chmax(T& a, T b) { if (a < b) {a = b; return true;} return false; } const int inf = 1e9; const ll INF = 4e18; template using pq = priority_queue, less>; template using spq = priority_queue, greater>; vector di = {0, 0, 1, -1}; vector dj = {1, -1, 0, 0}; struct Edge { int to, cost; }; void solve() { ll N; cin >> N; ll P = 1; N++; vector cnt(1); for (int i = 1; ; i++) { P = lcm(P, i); if (P > N) break; //r >= xP and xP/i >= l なる x が存在する (l, r) の個数 //P/i = Q とおく。 //x = floor(r/P) としてよい。 //xを固定したとき、rの個数は x <= r/P < x+1 より、Px <= r < P(x+1) の P個 //lの個数は l <= xQ より、xQ個 //xについて総和をとって、sum_{x}(PQx) + 余り //P(x+1) <= N (<=> x <= N/P-1) のとき、(l, r) の個数は PQx //x = N/P のとき、rの個数は N - Px 個、lの個数はxQ個 ll Q = P / i; assert(N / P != 0); mint ans = 0; { mint PQ = mint(P) * Q; //x = 0 ~ N/P-1まで:総和 N/P(N/P-1)/2 ans += (mint(N/P)*(N/P-1)/2) * PQ; } { ll x = N / P; ans += mint(N - P * x) * mint(x * Q); } cnt.push_back(ans); } mint fa = 0; for (mint x : cnt) fa += x; cout << fa.val() << endl; } int main() { int T; cin >> T; while(T--) solve(); }