// これは不正解のはず #include // clang-format off using namespace std;constexpr int INF=1001001001;constexpr long long INFll=1001001001001001001;namespace viewer{using s=string;templates f(T i){s S=i==INF||i==INFll?"inf":to_string(i);return s(max(0,3-int(S.size())),' ')+S;} templateauto v(T&x,s&&e)->decltype(cerr<void v(const pair&p,s&&e="\n"){cerr<<"(";v(p.first,", ");v(p.second,")"+e);}templatevoid v(const tuple&t,s&&e="\n"){cerr<<"(";v(get<0>(t),", ");v(get<1>(t),")"+e);}templatevoid v(const tuple&t,s&&e="\n"){cerr<<"(";v(get<0>(t),", ");v(get<1>(t),", ");v(get<2>(t),")"+e);}templatevoid v(const tuple&t,s&&e="\n"){cerr<<"(";v(get<0>(t),", ");v(get<1>(t),", ");v(get<2>(t),", ");v(get<3>(t),")"+e);} templatevoid v(const vector&vx,s);templateauto ve(int,const vector&vx)->decltype(cerr<auto ve(bool,const vector&vx){cerr<<"{\n";for(const T&x:vx)cerr<<" ",v(x,",");cerr<<"}\n";}templatevoid v(const vector&vx,s){ve(0,vx);} templatevoid v(const deque&q,s&&e){v(vector(q.begin(),q.end()),e);}templatevoid v(const set&S,s&&e){v(vector(S.begin(),S.end()),e);}templatevoid v(const multiset&S,s&&e){v(vector(S.begin(),S.end()),e);}templatevoid v(const unordered_set&S,s&&e){v(vector(S.begin(),S.end()),e);} templatevoid v(const priority_queue&p,s&&e){priority_queueq=p;vectorz;while(!q.empty()){z.push_back(q.top());q.pop();}v(z,e);}templatevoid v(const map&m,s&&e){cerr<<"{"<<(m.empty()?"":"\n");for(const auto&kv:m){cerr<<" [";v(kv.first,"");cerr<<"] : ";v(kv.second,"");cerr<<"\n";}cerr<<"}"+e;} templatevoid _view(int n,s&S,T&var){cerr<<"\033[1;32m"<void grid(T _){}void grid(const vector>&vvb){cerr<<"\n";for(const vector&vb:vvb){for(const bool&b:vb)cerr<<(b?".":"#");cerr<<"\n";}} void _debug(int,s){}templatevoid _debug(int n,s S,const H&h,const T&... t){int i=0,cnt=0;for(;iap;mint re=a;for(long long r=1;r prime_table(int n) { assert(n >= 1); vector isp(n + 1, false); if (n == 1) return isp; isp[2] = 1; for (int i = 3; i <= n; i += 2) isp[i] = true; for (int p = 3; p * p <= n; p += 2) if (isp[p]) for (int q = p * p; q <= n; q += (p << 1)) isp[q] = false; return isp; } template T gcd(vector& Xs) { T ret = abs(Xs[0]); for (T x : Xs) ret = gcd(ret, abs(x)); return ret; } template vector divisors(T n) { vector ret; for (T i = 1; i * i <= n; i++) { if (n % i == 0) { ret.push_back(i); if (i * i != n) ret.push_back(n / i); } } sort(begin(ret), end(ret)); return ret; } void check_slow(const int M, const vector& ans) { int cnt = 0; for (int bit = 1; bit < (1 << int(ans.size())); bit++) { vector temp; for (int i = 0; i < int(ans.size()); i++) { if (bit & (1 << i)) { temp.push_back(ans[i]); } } if (gcd(temp) >= 2) { cnt++; } } assert(cnt == M); } void check_fast(const int M, const vector& ans) { vector dp(100000 + 1, 0); for (auto& a : ans) { for (auto& d : divisors(a)) { if (d == 1) { continue; } dp[d]++; } } for (int i = 100000; i > 1; i--) { dp[i] = mint(2).pow(dp[i].val()) - 1; for (int j = 2 * i; j <= 100000; j += i) { dp[i] -= dp[j]; } } assert(mint(M).val() == accumulate(dp.begin(), dp.end(), mint(0)).val()); } void check(const int M, const vector& ans) { vector ans2 = ans; sort(ans2.begin(), ans2.end()); ans2.erase(unique(ans2.begin(), ans2.end()), ans2.end()); assert(ans.size() == ans2.size()); assert(*min_element(ans.begin(), ans.end()) >= 1); assert(*max_element(ans.begin(), ans.end()) <= 100000); if (M <= 10) { check_slow(M, ans); } check_fast(M, ans); } int get_prime(vector& isp) { for (int i = 0; i < 100000; i++) { if (isp[i]) { isp[i] = false; return i; } } assert(false); } int main() { cin.tie(0); ios::sync_with_stdio(false); vector isp = prime_table(100000); int M; cin >> M; assert(0 <= M && M < 998244353); if (M == 0) { M = 998244353; } vector ans; vector coefs(__builtin_popcount(M)); // 大きい数字になるといけないので、各グループのベースとなる素数はあらかじめ確保しておく for (auto& e : coefs) { e = get_prime(isp); } // bit毎に考える for (int bit = 0; bit <= 30; bit++) { if (M & (1 << bit)) { vector temp; // 別々の素数を用意し、 for (int i = 0; i < bit; i++) { temp.push_back(get_prime(isp)); } // 最初に用意したベースを乗算する for (auto& p : temp) { p *= coefs.back(); } coefs.pop_back(); // 空集合の分を加える temp.push_back(get_prime(isp)); ans.insert(ans.end(), temp.begin(), temp.end()); } } check(M, ans); cout << ans.size() + 1 << endl; for (auto& elem : ans) cout << elem << ' '; cout << ans.back() << endl; return 0; }