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

#ifdef SG
	#include <debug.h>
#else
	template<typename T> struct outputer;
	struct outputable {};
	#define PRINT(...)
	#define OUTPUT(...)
	#define show(...)
	#define debug(...)
	#define deepen(...)
	#define timer(...)
	#define fbegin(...)
	#define fend
	#define pbegin(...)
	#define pend
#endif

#define ARG4(_1,_2,_3,_4,...) _4

#define forn3(i,l,r) for (int i = int(l); i < int(r); ++i)
#define forn2(i,n) forn3 (i, 0, n)
#define forn(...) ARG4(__VA_ARGS__, forn3, forn2) (__VA_ARGS__)

#define ford3(i,l,r) for (int i = int(r) - 1; i >= int(l); --i)
#define ford2(i,n) ford3 (i, 0, n)
#define ford(...) ARG4(__VA_ARGS__, ford3, ford2) (__VA_ARGS__)

#define ve vector
#define pa pair
#define tu tuple
#define mp make_pair
#define mt make_tuple
#define pb emplace_back
#define fs first
#define sc second
#define all(a) (a).begin(), (a).end()
#define sz(a) ((int)(a).size())

typedef long double ld;
typedef int64_t ll;
typedef uint64_t ull;
typedef uint32_t ui;
typedef uint16_t us;
typedef uint8_t uc;
typedef pa<int, int> pii;
typedef pa<int, ll> pil;
typedef pa<ll, int> pli;
typedef pa<ll, ll> pll;
typedef ve<int> vi;

template<typename T> inline auto sqr (T x) -> decltype(x * x) {return x * x;}
template<typename T1, typename T2> inline bool umx (T1& a, T2 b) {if (a < b) {a = b; return 1;} return 0;}
template<typename T1, typename T2> inline bool umn (T1& a, T2 b) {if (b < a) {a = b; return 1;} return 0;}

const int N = 1000000;
const ll mod = 998244353;

struct Input {
	int n;
	
	bool read() {
		return !!(cin >> n);
	}

	void init(const Input &input) {
		*this = input;
	}
};

struct Data: Input {
	ll ans;
	
	void write() {
		cout << ans << endl;
	}
};


namespace Main {
	const ll inv2 = (mod + 1) / 2;
	const ll inv6 = (mod + 1) / 6;
	
	struct Solution: Data {
		ll a[4][N + 1]; // d <= i, l = j
		ll s[N + 2]; // d <= 2, l < i
		
		void solve() {
			memset(a, 0, sizeof a);
			memset(s, 0, sizeof s);
			forn (i, N + 1) {
				if (i == 0) {
					a[0][i] = 1;
					a[1][i] = 1;
					a[2][i] = 1;
					a[3][i] = 1;
				} else {
					a[1][i] = a[2][i - 1];
					a[2][i] = a[1][i];
					(a[2][i] += a[2][i - 1] * s[i - 1]) %= mod;
					(a[2][i] += a[2][i - 1] * (a[2][i - 1] + 1) % mod * inv2) %= mod;
					a[3][i] = a[2][i];
					(a[3][i] += a[2][i - 1] * s[i - 1] % mod * (s[i - 1] + 1) % mod * inv2) %= mod;
					(a[3][i] += a[2][i - 1] * (a[2][i - 1] + 1) % mod * s[i - 1] % mod * inv2) %= mod;
					(a[3][i] += a[2][i - 1] * (a[2][i - 1] + 1) % mod * (a[2][i - 1] + 2) % mod * inv6) %= mod;
				}
				s[i + 1] = (s[i] + a[2][i]) % mod;
			}
			forn (i, 4) {
				debug(a[i], a[i] + 10);
			}
			ans = ((a[3][n] + mod - a[1][n]) * 2 + a[1][n]) % mod;
			debug(ans);
			forn (i, n + 1) {
				(ans += (a[2][i] + mod - a[1][i]) * (a[1][n - i] + mod - a[0][n - i])) %= mod;
			}
		}
		
		void clear() {
			*this = Solution();
		}
	};
}


Main::Solution sol;

int main() {
	cout.setf(ios::showpoint | ios::fixed);
	cout.precision(20);

	#ifdef SG
		freopen((problemname + ".in").c_str(), "r", stdin);
//		freopen((problemname + ".out").c_str(), "w", stdout);
		while (sol.read()) {
			sol.solve();
			sol.write();
			sol.clear();
		}
	#else
		sol.read();
		sol.solve();
		sol.write();
	#endif
	
	/*
	int t;
	cin >> t;
	forn (i, t) {
		sol.read();
		sol.solve();
		sol.write();
		sol.clear();
	}
	*/
	
	return 0;
}
