/*#pragma GCC target ("avx2")
#pragma GCC optimization ("Ofast")
#pragma GCC optimization ("unroll-loops")*/

//#include "jumps.h"

#include <iostream>
#include <utility>
#include <vector>
#include <cmath>
#include <algorithm>
#include <unordered_set>
#include <set>
#include <queue>
#include <cmath>
#include <numeric>
#include <sstream>
#include <string>
#include <map>
#include <unordered_map>
#include <deque>
#include <iomanip>
#include <unordered_set>
#include <limits>
#include <list>
#include <bitset>
#include <random>
#include <cstring>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>

//#include <bits/stdc++.h>
using namespace std;
//using namespace __gnu_pbds;
//
//template <typename T>
//using indexed_set = tree<
//        T,
//        null_type,
//        less<T>,
//        rb_tree_tag,
//        tree_order_statistics_node_update>;

using ll = long long;
using ld = long double;
template<typename T>
using v = vector<T>;
template<typename ...T>
using tup = tuple<T...>;
template<typename T1, typename T2>
using pa = pair<T1, T2>;
const ld PI = 3.1415926535;
const ll MOD = 998244353;

mt19937 rng;

template<typename T>
inline pa<T, T> operator+(pa<T, T> a, pa<T, T> b) {
    return { a.first + b.first, a.second + b.second };
}

template<typename T>
inline pa<T, T> operator+=(pa<T, T>& a, pa<T, T> b) {
    return a = a + b;
}

template<typename T>
inline pa<T, T> operator-(pa<T, T> a, pa<T, T> b) {
    return { a.first - b.first, a.second - b.second };
}

template<typename T>
inline pa<T, T> operator-=(pa<T, T>& a, pa<T, T> b) {
    return a = a - b;
}

template<typename T>
inline pa<T, T> operator*(pa<T, T> a, T b) {
    return { a.first * b, a.second * b };
}

template<typename T>
inline pa<T, T> operator*=(pa<T, T>& a, T b) {
    return a = a * b;
}
template<typename T>
inline pa<T, T> operator/(pa<T, T> a, T b) {
    return { a.first / b, a.second / b };
}

template<typename T>
inline pa<T, T> operator/=(pa<T, T>& a, T b) {
    return a = a / b;
}

template<typename T>
inline T cross(pa<T, T> a, pa<T, T> b) {
    return a.first * b.second - a.second * b.first;
}

template<typename T>
inline T dot(pa<T, T> a, pa<T, T> b) {
    return a.first * b.first + a.second * b.second;
}

template<typename T>
inline T operator*(pa<T, T> a, pa<T, T> b) {
    return dot(a, b);
}

template<typename T>
inline T operator^(pa<T, T> a, pa<T, T> b) {
    return cross(a, b);
}

template<typename T>
inline std::istream& operator>>(std::istream& in, pa<T, T>& pa) {
    //return a.first * b.second - a.second * b.first;
    return in >> pa.first >> pa.second;
}

template<typename T>
inline std::ostream& operator<<(std::ostream& out, pa<T, T>& pa) {
    //return a.first * b.second - a.second * b.first;
    return out << pa.first << ' ' << pa.second;
}

template<typename T>
inline std::istream& operator>>(std::istream& in, v<T>& a) {
    for (ll i = 0; i < a.size(); ++i) {
        in >> a[i];
    }
    return in;
}
template<typename T>
inline std::ostream& operator<<(std::ostream& out, v<T>& a) {
    for (ll i = 0; i < a.size(); ++i) {
        out << a[i] << ' ';
    }
    return out;
}

template<typename T>
inline T sqrLength(pa<T, T> pa) {
    return pa.first * pa.first + pa.second * pa.second;
}

template<typename T>
inline T length(pa<T, T> pa) {
    return sqrt(sqrLength(pa));
}

template<typename T>
inline T manhattanLength(pa<T, T> pa) {
    return abs(pa.first) + abs(pa.second);
}

template<typename T>
inline T manhattanDistance(pa<T, T> a, pa<T, T> b) {
    return manhattanLength(a - b);
}

template<typename T>
inline pa<T, T> normalize(pa<T, T> pa) {
    return pa / length(pa);
}

inline pa<ld, ld> toLd(pa<ll, ll> pa) {
    return { (ld)pa.first, (ld)pa.second };
}

template<typename T>
inline T sign(T n) {
    if (n > 0) {
        return 1;
    }
    else if (n == 0) {
        return 0;
    }
    else {
        return -1;
    }
}

bool point_in_aabb(pa<ll, ll> a, pa<ll, ll> b, pa<ll, ll> x) {
    return x.first >= min(a.first, b.first) && x.first <= max(a.first, b.first) && x.second >= min(a.second, b.second) && x.second <= max(a.second, b.second);
}

bool point_on_segm(pa<ll, ll> a, pa<ll, ll> b, pa<ll, ll> x) {
    if (((b - a) ^ (x - a)) == 0) {
        return point_in_aabb(a, b, x);
    }
    else {
        return false;
    }
}

bool point_in_triangle(pa<ll, ll> a, pa<ll, ll> b, pa<ll, ll> c, pa<ll, ll> p) {
    ll s = abs((b - a) ^ (c - a));
    ll s1 = abs((p - a) ^ (c - a));
    ll s2 = abs((b - a) ^ (p - a));
    ll s3 = abs((b - p) ^ (c - p));
    return s == s1 + s2 + s3;
}

void solve() {
    ll n;
    cin >> n;
    v<ll> resheto(n + 1);
    v<ll> dcnt(n + 1);
    dcnt[1] = 1;
    for (ll i = 2; i <= n; ++i) {
        if (resheto[i] == 0) {
            for (ll j = i; j <= n; j += i) {
                resheto[j] = i;
            }
        }
        ll ma_d = resheto[i];
        ll macnt = 0;
        ll pn = i;
        while (resheto[pn] == ma_d) {
            ++macnt;
            pn /= ma_d;
        }
        dcnt[i] = dcnt[pn] * (macnt + 1);
    }
    v<ll> dp(n + 1);
    ll pref = 0;
    for (ll i = 1; i <= n; ++i) {
        ll bw = (dcnt[i] + pref) % MOD;
        dp[i] = bw;
        pref += bw;
        pref %= MOD;
    }
    cout << dp[n];
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    ll t = 1;
    //cin >> t;
    for (ll i = 0; i < t; ++i) {
        solve();
    }
}