#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
# define rep(i,a,b) for(int i=(a); i<=(b); ++i)
# define drep(i,a,b) for(int i=(a); i>=(b); --i)
typedef long long int_;
inline int readint(){
	int a = 0; char c = getchar(), f = 1;
	for(; c<'0'||c>'9'; c=getchar())
		if(c == '-') f = -f;
	for(; '0'<=c&&c<='9'; c=getchar())
		a = (a<<3)+(a<<1)+(c^48);
	return a*f;
}
inline void getMin(int &a,const int &b){
	if(a > b) a = b;
}

const int Mod = 998244353;
inline void add(int &x,const int &y){
	(x += y) >= Mod ? x -= Mod : 0;
}
inline void mul(int &x,const int &y){
	x = int_(x)*y%Mod;
}
int inv[4] = {0,1,(Mod+1)/2,(Mod+1)/3};
inline int C(const int &n,const int &m){
	int res = 1;
	rep(i,1,m) mul(res,inv[i]);
	rep(i,0,m-1) mul(res,n-i);
	return res;
}

const int MaxN = 1000005;
const int infty = (1<<30)-1;
int dp[MaxN][4]; // prefix sum

int main(){
	int n = readint(), x;
	dp[0][0] = 1; // only one node
	rep(i,1,n) rep(j,0,3){
		rep(k,x=0,2) // at most 2
			add(x,dp[i-1][k]);
		dp[i][j] = C(j+x-1,j);
	}
	drep(i,n,1) rep(j,0,3) // get origin value
		add(dp[i][j],Mod-dp[i-1][j]);
	int ans = 0;
	rep(i,1,n) rep(j,2,3) rep(k,0,3-j)
		add(ans,1ll*dp[i][j]*dp[n-i][k]%Mod);
	rep(j,0,3) add(ans,dp[n][j]);
	printf("%d\n",ans);
	return 0;
}
