#include #include using namespace std; using i32 = int; using i64 = long long; using i128 = __int128_t; using f64 = double; using p2 = pair; using el = tuple; using mint = atcoder::modint998244353; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); cout << fixed << setprecision(18); _main(); } void _main() { vector fac(100, 1), finv(100, 1), inv(100, 0); inv[1] = 1; i64 mod = 998244353; for (i64 i = 2; i < fac.size(); i++) { fac[i] = fac[i - 1] * i; inv[i] = -inv[mod % i] * (mod / i); finv[i] = finv[i - 1] * inv[i]; } i64 n; cin >> n; n++; mint ans = 0; for (i64 i = 0; i < 60; i++) { if (n <= (1ll << i)) continue; vector dp(70, 0); mint x = 1; i64 cnt = 0; bool f = true; for (i64 j = 60; j >= 0; j--) { if ((n >> j) == 0) continue; vector ndp(70, 0); if (j == i) { if (f) { f = false; } else { ndp[1]++; for (i64 k = 0; k < dp.size(); k++) { if (k + 1 < dp.size()) ndp[k + 1] += dp[k]; } if (n >> j & 1) { } else x = 0; } } else { if (f) { f = false; } else { if (i < j) ndp[1]++; for (i64 k = 0; k < dp.size(); k++) { if (k + 1 < dp.size()) ndp[k + 1] += dp[k]; ndp[k] += dp[k]; } if (n >> j & 1) { ndp[cnt] += x; } } } if (n >> j & 1) { cnt++; } swap(dp, ndp); } for (i64 j = 0; j < dp.size(); j++) { ans += dp[j] * dp[j] * mint(2).pow(i); } } ans += n * (n - 1) / 2; ans /= 2; cout << ans.val() << "\n"; }