#include #include #pragma GCC optimize("Ofast") #pragma GCC target("avx2") #pragma GCC optimize("unroll-loops") #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") #define rep(i,n) for(ll i = 0LL; i < (ll)n; ++i) #define rep1(i,n) for(ll i = 1LL; i <= (ll)n; ++i) #define rep2(i,m,n) for(ll i = (ll)m; i < (ll)n; ++i) #define rrep(i,n) for(ll i = (ll)n - 1; i >= 0LL; --i) #define rrep1(i,n) for(ll i = (ll)n; i > 0LL; --i) #define rrep2(i,m,n) for(ll i = (ll)m; i > (ll)n; --i) #define lb(a,x) static_cast(lower_bound(all(a), x) - a.begin()) #define ub(a,x) static_cast(upper_bound(all(a), x) - a.begin()) #define all(a) a.begin(), a.end() #define rall(a) a.rbegin(), a.rend() #define SORT(a) sort(all(a)); #define RSORT(a) sort(rall(a)); #define REV(a) reverse(all(a)); #define CEIL(x,y) (x+y-1)/y #define pb push_back #define eb emplace_back #define _GLIBCXX_DEBUG #define _CRT_SECURE_NO_WARNINGS #define INT(...) int __VA_ARGS__;in(__VA_ARGS__) #define LL(...) ll __VA_ARGS__;in(__VA_ARGS__) #define STR(...) string __VA_ARGS__;in(__VA_ARGS__) #define CHR(...) char __VA_ARGS__;in(__VA_ARGS__) #define DBL(...) double __VA_ARGS__;in(__VA_ARGS__) #define LD(...) ld __VA_ARGS__;in(__VA_ARGS__) using namespace std; using namespace chrono; using namespace atcoder; using ld = long double; using ll = long long; using ull = unsigned long long; using vi = vector; using vl = vector; using vc = vector; using vb = vector; using vs = vector; using vvi = vector; using vvl = vector; using vvc = vector; using vvb = vector; using vvs = vector; using pii = pair; using pll = pair; using si = set; using sl = set; using mii = map; using mll = map; //in void in(){} templatevoid in(vector &v){ for(T &t : v)cin >> t; } templatevoid in(vector> &v){ for(auto &row : v)for(T&element : row)cin >> element; } templatevoid in(Head &head, Tail &...tail){ cin >> head; in(tail...); } //out void out(){} templatevoid out(const T &t){ cout << t << endl; } templatevoid out(vector &v){ for(T &t : v)cout << t << ' '; cout << endl; } templatevoid out(vector> &v){ for(vector &row : v){ for(T &element : row){ cout << element << ' '; } cout << endl; } } templatevoid out(const Head &head, const Tail &...tail){ cout << head; out(tail...); } //chmax templatebool chmax(T &a, T b){ return((a < b)? (a = b, true) : (false)); } //chmin templatebool chmin(T &a, T b){ return((a > b)? (a = b, true) : (false)); } //min templateT MIN(vector &v){ T mn = numeric_limits::max(); for(T &e : v){ mn = min(mn, e); } return mn; } //max templateT MAX(vector &v){ T mx = numeric_limits::min(); for(T &e : v){ mx = max(mx, e); } return mx; } //sum templateT SUM(vector &v){ T sum = 0; for(T &e : v){ sum += e; } return sum; } //l_sort templatevoid l_sort(vector &l, vector &r){ assert(l.size() == r.size()); long long n = l.size(); vector> p; for(ll i = 0; i < n; i++){ p.emplace_back(l[i], r[i]); } sort(p.begin(), p.end()); for(ll i = 0; i < n; i++){ l[i] = p[i].first; r[i] = p[i].second; } } //r_sort templatevoid r_sort(vector &l, vector &r){ assert(l.size() == r.size()); long long n = l.size(); vector> p; for(ll i = 0; i < n; i++){ p.emplace_back(r[i], l[i]); } sort(p.begin(), p.end()); for(ll i = 0; i < n; i++){ l[i] = p[i].second; r[i] = p[i].first; } } //-----------------------array-----------------------// //cumulative_sum template vector cumulative_sum(vector &v){ ll n = v.size(); vector res(n + 1); for(ll i = 0; i < n; ++i){ res[i + 1] = res[i] + v[i]; } return res; } //LCS ll LCS(string s, string t){ vector dp(s.size() + 1,vector(t.size() + 1)); rep(i,s.size()){ rep(j,t.size()){ if(s[i] == t[j]){ dp[i + 1][j + 1] = max({dp[i][j + 1],dp[i + 1][j],dp[i][j] + 1}); }else{ dp[i + 1][j + 1] = max(dp[i][j + 1],dp[i + 1][j]); } } } return dp[s.size()][t.size()]; } //LIS templatell LIS(vector &a){ vector dp; for (T &e : a){ auto it = lower_bound(dp.begin(), dp.end(), e); if (it == dp.end()){ dp.push_back(e); }else{ *it = e; } } return (ll)dp.size(); } template< typename T > struct Compress { vector< T > xs; Compress() = default; Compress(const vector< T > &vs) { add(vs); } Compress(const initializer_list< vector< T > > &vs) { for(auto &p : vs) add(p); } void add(const vector< T > &vs) { copy(begin(vs), end(vs), back_inserter(xs)); } void add(const T &x) { xs.emplace_back(x); } void build() { sort(begin(xs), end(xs)); xs.erase(unique(begin(xs), end(xs)), end(xs)); } vector< ll > get(const vector< T > &vs) const { vector< ll > ret; transform(begin(vs), end(vs), back_inserter(ret), [&](const T &x) { return lower_bound(begin(xs), end(xs), x) - begin(xs); }); return ret; } ll get(const T &x) const { return lower_bound(begin(xs), end(xs), x) - begin(xs); } const T &operator[](ll k) const { return xs[k]; } }; ll edit_distance(string &s, string &t){ ll n = s.size(), m = t.size(); vector dp(n + 1, vector(m + 1)); for(ll i = 1; i <= n; i++)dp[i][0] = i; for(ll j = 1; j <= m; j++)dp[0][j] = j; for(ll i = 1; i <= n; i++)for(ll j = 1; j <= m; j++){ dp[i][j] = min({dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + (s[i - 1] == t[j - 1]? 0 : 1)}); } return dp[n][m]; } //--------------------data_structure-----------------// //suffix_array struct suffix_array{ vector sa, rank, tmp; ll n; string base; //suffix_arrayを構築 suffix_array(const string s){ n = s.size(); base = s; sa.resize(n); rank.resize(n); tmp.resize(n); for(ll i = 0; i < n; i++){ sa[i] = i; rank[i] = s[i]; } for(ll k = 1; k < n; k *= 2){ auto compare_sa = [&](ll i, ll j){ if(rank[i] != rank[j])return rank[i] < rank[j]; ll ri = (i + k < n) ? rank[i + k] : -1; ll rj = (j + k < n) ? rank[j + k] : -1; return ri < rj; }; sort(sa.begin(), sa.end(), compare_sa); tmp[sa[0]] = 0; for(ll i = 1; i < n; i++){ tmp[sa[i]] = tmp[sa[i - 1]] + (compare_sa(sa[i - 1], sa[i])? 1 : 0); } rank = tmp; } } //部分文字列の個数を求める ll get_counts(string t){ string u = t + "彁"; ll num1, num2; { ll m = t.size(); ll ng = -1, ok = n; while(ok - ng > 1){ ll mid = (ng + ok) / 2; ll l = sa[mid]; if(base.substr(l, m) >= t){ ok = mid; }else{ ng = mid; } } num1 = ok; } { ll m = u.size(); ll ng = -1, ok = n; while(ok - ng > 1){ ll mid = (ng + ok) / 2; ll l = sa[mid]; if(base.substr(l, m) >= u){ ok = mid; }else{ ng = mid; } } num2 = ok; } return num2 - num1; } }; //-----------------------check-----------------------// //is_prime template bool is_prime(T n){ if(n <= 1)return false; T m = sqrt(n); for(ll i = 2; i <= m; ++i){ if(n % i == 0)return false; } return true; } //is_square template bool is_square(T n){ if(n < 0)return false; T m = sqrt(n); if(n == m * m){ return true; }else{ return false; } } //is_substring bool is_substring(const string& s, const string& t){ const ll n = s.size(), m = t.size(); for(ll i = 0; i + m <= n; ++i){ if(s.substr(i, m) == t)return true; } return false; } //-----------------------math------------------------// //gcd(faster) ll GCD(ll A, ll B){ if(B == 0){ return A; }else{ return GCD(B, A % B); } } //lcm(faster) ll LCM(ll A, ll B){ return A / GCD(A, B) * B; } //comb ll comb(ll n, ll r){ assert(n >= 2); vector dp(n + 1, vector(r + 1)); for(ll i = 0; i < n + 1; ++i){ dp[i][0] = 1; } for(ll i = 0; i < r + 1; ++i){ dp[i][i] = 1; } for(ll i = 1; i < n + 1; ++i){ for(ll j = 1; j < min(i, r + 1); ++j){ dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]; } } return dp[n][r]; } // comb_mod using mint_comb = atcoder::static_modint<1000000007>; vector fac, finv, inv; // テーブルを作る前処理 void init_comb_mod(ll size) { size += 109; fac.resize(size); finv.resize(size); inv.resize(size); const ll MOD = mint_comb::mod(); fac[0] = fac[1] = 1; finv[0] = finv[1] = 1; inv[1] = 1; for (ll i = 2; i < size; i++){ fac[i] = fac[i - 1] * i; inv[i] = MOD - inv[MOD%i] * (MOD / i); finv[i] = finv[i - 1] * inv[i]; } } // 二項係数計算 mint_comb comb_mod(ll n, ll k){ if (n < k) return 0; if (n < 0 || k < 0) return 0; return fac[n] * finv[k] * finv[n - k]; } //make_random //long long ll rand_ll(ll l, ll r){ if(l > r)swap(l, r); random_device rd; mt19937_64 gen(rd()); uniform_int_distributiondis(l, r); return dis(gen); } //int int rand_int(int l, int r){ if(l > r)swap(l, r); return l + rand() % (r - l + 1); } //double ld rand_double(){ return (ld)1.0 * rand() / RAND_MAX; } //base_conversion ll ntodec(const char c){ if(c >= '0' && c <= '9'){ return (ll)c - '0'; }else{ return (ll)c - 55; } } char decton(const ll n){ if(n >= 0 && n <= 9){ return (char)'0' + n; }else{ return (char)55 + n; } } inline ll pow_ll(ll x,ll n){ ll ret = 1; rep(i,n){ ret *= x; } return ret; } string base_conversion(string str, ll n, ll m){ ull tmp = 0; string ret; rep(i,str.size()){ tmp += (ull)ntodec(str[str.size() - 1 - i]) * pow_ll(n, i); } if(tmp == 0){ return "0"; } while(tmp != 0){ ret = decton(tmp % m) + ret; tmp /= m; } return ret; } //calc_triangle long double calc_triangle(long double x1,long double y1,long double x2,long double y2,long double x3,long double y3){ return abs((x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) / 2.0); } //文字列の最小周期 vector computeLPSArray(const string& pattern) { ll m = pattern.length(); vector lps(m); ll len = 0; lps[0] = 0; ll i = 1; while (i < m) { if (pattern[i] == pattern[len]) { len++; lps[i] = len; i++; } else { if (len != 0) { len = lps[len - 1]; } else { lps[i] = 0; i++; } } } return lps; } ll findMinimumPeriod(const string& str) { ll n = str.length(); vector lps = computeLPSArray(str); ll len = lps[n - 1]; ll period = n - len; if (n % period == 0) { return period; } else { return n; } } //-----------------------graph-----------------------// //graph_template struct Edge{ ll to; ll cost; Edge(ll to, ll cost) : to(to), cost(cost) {} bool operator>(const Edge &e) const{ return cost > e.cost; } bool operator<(const Edge &e) const{ return cost < e.cost; } }; struct Edge2{ ll from; ll to; ll cost; Edge2(ll from, ll to, ll cost) : from(from), to(to), cost(cost) {} bool operator>(const Edge2 &e) const{ return cost > e.cost; } bool operator<(const Edge2 &e) const{ return cost < e.cost; } }; struct Edge3 { ll to; Edge3(ll to) : to(to) {} }; struct Graph{ Graph() = default; vector> G; Graph(ll N){ G.resize(N); } ll size(){ return G.size(); } void add_edge(ll from, ll to, ll cost = 1){ G[from].push_back(Edge(to, cost)); G[to].push_back(Edge(from, cost)); } void add_directed_edge(ll from, ll to, ll cost = 1){ G[from].push_back(Edge(to, cost)); } vector &operator[](ll v){ return G[v]; } }; //dijkstra struct dijkstra{ vector dist; vector prev; //dijkstraを構築 dijkstra(Graph &G, ll s){ ll N = G.size(); dist.assign(N, 1LL << 60); prev.assign(N, -1); priority_queue, vector>, greater>> pq; dist[s] = 0; pq.emplace(dist[s], s); while (!pq.empty()){ auto p = pq.top(); pq.pop(); ll v = p.second; if(dist[v] < p.first)continue; for (auto &e : G[v]){ if (dist[e.to] > dist[v] + e.cost){ dist[e.to] = dist[v] + e.cost; prev[e.to] = v; pq.emplace(dist[e.to], e.to); } } } } //最小コストを求める ll get_cost(ll to){ return dist[to]; } //最短経路を求める vector get_path(ll to){ vector get_path; for (ll i = to; i != -1; i = prev[i]){ get_path.push_back(i); } reverse(get_path.begin(), get_path.end()); return get_path; } //到達可能か調べる bool cango(ll to){ return dist[to] != 1LL << 60; } }; //bellman_ford struct bellman_ford{ vector dist; vector prev; ll start; ll n; bool cl = false; //bellman_fordを構築 bellman_ford(Graph &g, ll s){ start = s; n = g.size(); dist.assign(n, 1LL << 60); prev.assign(n, -1); vector counts(n); vector inqueue(n); queue q; dist[s] = 0; q.push(s); inqueue[s] = true; while(!q.empty()){ ll from = q.front(); q.pop(); inqueue[from] = false; for(auto &e : g[from]){ ll d = dist[from] + e.cost; if(d < dist[e.to]){ dist[e.to] = d; prev[e.to] = from; if(!inqueue[e.to]){ q.push(e.to); inqueue[e.to] = true; ++counts[e.to]; if(n < counts[e.to])cl = true; } } } } } //最小コストを求める ll get_cost(ll to){ return dist[to]; } //最短経路を求める vector get_path(ll to){ vector path; if(dist[to] != 1LL << 60){ for(ll i = to; i != -1; i = prev[i]){ path.push_back(i); } reverse(path.begin(), path.end()); } return path; } //到達可能か調べる bool cango(ll to){ return (dist[to] != 1LL << 60); } //負の閉路の有無を調べる bool closed(){ return cl; } }; //warshall_floyd struct warshall_floyd{ vector> d; vector> next; bool cl = false; //warshall_floydを構築 warshall_floyd(Graph &g){ ll n = g.size(); d.resize(n, vector(n, 1LL << 60)); next.resize(n, vector(n, -1)); for(ll i = 0; i < n; i++){ d[i][i] = 0; } for(ll i = 0; i < n; i++){ for(auto e : g[i]){ d[i][e.to] = e.cost; next[i][e.to] = e.to; } } for(ll k = 0; k < n; ++k){ for(ll i = 0; i < n; ++i){ for(ll j = 0; j < n; ++j){ if(d[i][k] == 1LL << 60 || d[k][j] == 1LL << 60)continue; if(d[i][j] > d[i][k] + d[k][j]){ d[i][j] = d[i][k] + d[k][j]; next[i][j] = next[i][k]; } } } } for(ll i = 0; i < n; i++){ if(d[i][i] < 0){ cl = true; break; } } } //最小コストを求める ll get_cost(ll from, ll to){ return d[from][to]; } //最短経路を求める vector get_path(ll from, ll to) { if (d[from][to] == 1LL << 60) return {}; vector path; for(ll at = from; at != to; at = next[at][to]){ if (at == -1) return {}; path.push_back(at); } path.push_back(to); return path; } //到達可能か調べる bool cango(ll from, ll to){ return d[from][to] != 1LL << 60; } //負の閉路の有無を調べる bool closed(){ return cl; } }; //UnionFind struct UnionFind{ vectorpar, rank, siz; UnionFind(ll n):par(n, -1), rank(n, 0), siz(n, 1){} ll root(ll x){ if(par[x] == -1){ return x; }else{ return par[x] = root(par[x]); } } //連結判定 bool issame(ll x, ll y){ return root(x) == root(y); } //連結 bool unite(ll x, ll y){ ll rx = root(x), ry = root(y); if(rx == ry){ return false; } if(rank[rx] < rank[ry]){ swap(rx, ry); } par[ry] = rx; if(rank[rx] == rank[ry]){ rank[rx]++; } siz[rx] += siz[ry]; return true; } ll size(ll x){ return siz[root(x)]; } }; struct kruskal{ ll n; vector edges; //kruskalの構築 kruskal(Graph &g){ n = g.size(); for(ll i = 0; i < n; i++){ for(auto e : g[i]){ edges.emplace_back(i, e.to, e.cost); } } } //最小全域木のコストを求める ll get_mincost(){ sort(edges.begin(), edges.end()); UnionFind uf(n); ll ret = 0; for(auto e : edges){ if(uf.unite(e.from, e.to))ret += e.cost; } return ret; } //最大全域木のコストを求める ll get_maxcost(){ sort(edges.rbegin(), edges.rend()); UnionFind uf(n); ll ret = 0; for(auto e : edges){ if(uf.unite(e.from, e.to))ret += e.cost; } return ret; } }; //木の直径を求める ll tree_diameter(Graph g){ ll n = g.size(); dijkstra d(g, 0); ll mx = 0, idx = -1; for(ll i = 0; i < n; i++){ if(mx < d.get_cost(i)){ mx = d.get_cost(i); idx = i; } } dijkstra d2(g, idx); ll mx2 = 0; for(ll i = 0; i < n; i++){ if(mx2 < d2.get_cost(i)){ mx2 = d2.get_cost(i); } } return mx2; } //LCA struct LCA { vector> parent; // parent[k][u]:= u の 2^k 先の親 vector dist; // root からの距離 LCA(Graph &g, ll root = 0){ vector> G(g.size()); for(ll i = 0; i < g.size(); i++){ for(auto e : g[i]){ G[i].emplace_back(e.to); } } ll V = G.size(); ll K = 1; while ((1 << K) < V) K++; parent.assign(K, vector(V, -1)); dist.assign(V, -1); dfs(G, root, -1, 0); for (ll k = 0; k + 1 < K; k++) { for (ll v = 0; v < V; v++) { if (parent[k][v] < 0) { parent[k + 1][v] = -1; } else { parent[k + 1][v] = parent[k][parent[k][v]]; } } } } void dfs(const vector> &G, ll v, ll p, ll d) { parent[0][v] = p; dist[v] = d; for (auto e : G[v]) { if (e.to != p) dfs(G, e.to, v, d + 1); } } ll query(ll u, ll v) { if (dist[u] < dist[v]) swap(u, v); // u の方が深いとする ll K = parent.size(); // LCA までの距離を同じにする for (ll k = 0; k < K; k++) { if ((dist[u] - dist[v]) >> k & 1) { u = parent[k][u]; } } // 二分探索で LCA を求める if (u == v) return u; for (ll k = K - 1; k >= 0; k--) { if (parent[k][u] != parent[k][v]) { u = parent[k][u]; v = parent[k][v]; } } return parent[0][u]; } ll get_dist(ll u, ll v){ return dist[u] + dist[v] - 2 * dist[query(u, v)]; } bool is_on_path(ll u, ll v, ll a){ return get_dist(u, a) + get_dist(a, v) == get_dist(u, v); } }; struct AuxiliaryTree { vector> G0; LCA &lca; AuxiliaryTree(LCA &lca) : lca(lca) {} void build(ll k, vector &vs) { sort(vs.begin(), vs.begin() + k, [&](ll a, ll b) { return lca.dist[a] < lca.dist[b]; }); stack stk; stk.push(vs[0]); G0[vs[0]].clear(); for (ll i = 1; i < k; ++i) { ll w = lca.query(vs[i - 1], vs[i]); if (w != vs[i - 1]) { ll last = stk.top(); stk.pop(); while (!stk.empty() && lca.dist[w] < lca.dist[stk.top()]) { G0[stk.top()].push_back(last); last = stk.top(); stk.pop(); } if (stk.empty() || stk.top() != w) { stk.push(w); vs.push_back(w); G0[w] = { last }; } else { G0[w].push_back(last); } } stk.push(vs[i]); G0[vs[i]].clear(); } while (stk.size() > 1) { ll u = stk.top(); stk.pop(); G0[stk.top()].push_back(u); } } }; //centroid_decomposition struct centroid_decomposition{ Graph g; ll n; vector size; ll centroid; centroid_decomposition(Graph f) : g(f){ g = f; n = g.size(); size.resize(n, 1); stack> st; st.push({0, 0, 0}); while (!st.empty()) { ll v, p, t; tie(v, p, t) = st.top(); st.pop(); if (t == 0) { st.push({v, p, 1}); for (auto [c, d] : g[v]) { if (c != p) { st.push({c, v, 0}); } } } else { bool is_centroid = true; for (auto [c, d] : g[v]) { if (c != p) { size[v] += size[c]; if (size[c] > n / 2) { is_centroid = false; } } } if (is_centroid && n - size[v] <= n / 2) { centroid = v; } } } } //木の重心を求める ll get_centroid(){ return centroid; } //重心によって分解された部分木を求める vector> get_subtree(){ vector> comp(n); stack> st; for(auto [v, w] : g[centroid]){ st.push({v, centroid, v}); } while(!st.empty()){ auto[v, p, i] = st.top(); st.pop(); comp[i].push_back(v); for(auto [c, d] : g[v]){ if(c != p){ st.push({c, v, i}); } } } return comp; } }; //----------------------normal-----------------------// const ld PI = 3.1415926535897932; const ll mod = 998244353; const ll MOD = 1000000007; const ll dx[] = {-1, 0, 1, 0, -1, 1, 1, -1}; const ll dy[] = {0, 1, 0, -1, 1, 1, -1, -1}; const string ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const string alpha = "abcdefghijklmnopqrstuvwxyz"; //using mint = modint; //using mint = static_modint<1777777777>; using mint = modint998244353; //using mint = modint1000000007; /*-----------------------function------------------------*/ bool f(string &s){ string t = s; reverse(t.begin(), t.end()); return s == t; } /*------------------------solve--------------------------*/ void solve(){ ll n; cin >> n; ll cnt = 0; rep(i,60){ if(1LL << i & n)cnt++; } cout << mint(2).pow(cnt).val() - 2 << endl; } int main(){ cin.tie(nullptr); cout.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); srand((unsigned)time(NULL)); //ll T; cin >> T; ll T = 1; while(T--){ solve(); } return 0; }