// https://szkopul.edu.pl/problemset/problem/iJJmCcYiYpjxJP682ai0jToE/site/?key=statement
// Trudny dylemat przedszkolanina
#include <bits/stdc++.h>
typedef unsigned long long ull;
typedef unsigned char u8;
typedef unsigned int u32;
const int NUM_PRIMES = 16;
const int primes[NUM_PRIMES] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53};
struct __attribute__((packed)) Candidate {
ull val;
u32 div_count;
u8 exps_lo[8];
u32 packed_hi;
};
ull N;
std::vector<Candidate> candidates;
ull approx_max_divisors = 0;
u8 current_exps_buffer[NUM_PRIMES];
bool can_reach_threshold(int p_idx, ull current_val, ull current_divs, ull threshold) {
if (current_divs >= threshold) return true;
if (p_idx >= NUM_PRIMES) return false;
ull p = primes[p_idx];
ull remaining = N / current_val;
if (remaining < p) return false;
ull temp_p = p;
ull estimated_divs = current_divs;
while (true) {
estimated_divs *= 2;
if (estimated_divs >= threshold) return true;
if (remaining / p < temp_p) break;
temp_p *= p;
}
return false;
}
void generate_candidates(int p_idx, ull current_val, ull current_divs) {
if (current_divs >= approx_max_divisors * 0.5) {
Candidate c;
c.val = current_val;
c.div_count = (u32)current_divs;
for (int i = 0; i < 8; ++i)
c.exps_lo[i] = current_exps_buffer[i];
c.packed_hi = 0;
for (int i = 8; i < 16; ++i) {
c.packed_hi |= ((u32)current_exps_buffer[i] << ((i - 8) * 4));
}
candidates.push_back(c);
}
if (p_idx >= NUM_PRIMES) return;
if (!can_reach_threshold(p_idx, current_val, current_divs, (ull)(approx_max_divisors * 0.5))) {
return;
}
ull p = primes[p_idx];
ull next_val = current_val;
for (int k = 0;; ++k) {
current_exps_buffer[p_idx] = k;
generate_candidates(p_idx + 1, next_val, current_divs * (k + 1));
if (N / p < next_val) break;
next_val *= p;
}
current_exps_buffer[p_idx] = 0;
}
void find_approx_max(int p_idx, ull current_val, ull current_divs, int last_exp) {
if (current_divs > approx_max_divisors) approx_max_divisors = current_divs;
if (p_idx >= NUM_PRIMES) return;
ull p = primes[p_idx];
ull next_val = current_val;
for (int k = 0; k <= last_exp; ++k) {
find_approx_max(p_idx + 1, next_val, current_divs * (k + 1), k);
if (N / p < next_val) break;
next_val *= p;
}
}
inline ull calc_gcd_divisors_fast(const Candidate& a, const Candidate& b) {
ull gcd_divs = 1;
for (int i = 0; i < 8; ++i) {
u8 e1 = a.exps_lo[i];
u8 e2 = b.exps_lo[i];
gcd_divs *= ((e1 < e2 ? e1 : e2) + 1);
}
u32 p1 = a.packed_hi;
u32 p2 = b.packed_hi;
for (int i = 0; i < 8; ++i) {
u8 e1 = p1 & 0xF;
u8 e2 = p2 & 0xF;
gcd_divs *= ((e1 < e2 ? e1 : e2) + 1);
p1 >>= 4;
p2 >>= 4;
}
return gcd_divs;
}
int main() {
std::ios_base::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
std::cin >> N;
memset(current_exps_buffer, 0, sizeof(current_exps_buffer));
find_approx_max(0, 1, 1, 60);
if (approx_max_divisors == 0) approx_max_divisors = 1;
candidates.reserve(600000);
generate_candidates(0, 1, 1);
ull best_union = 0;
ull best_x = 1, best_y = 1;
sort(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b) { return a.div_count > b.div_count; });
if (!candidates.empty()) {
best_union = candidates[0].div_count;
best_x = candidates[0].val;
best_y = candidates[0].val;
} else {
std::cout << "1\n1 1\n";
return 0;
}
for (size_t i = 0; i < candidates.size(); ++i) {
if (2 * (ull)candidates[i].div_count <= best_union) break;
for (size_t j = i; j < candidates.size(); ++j) {
if ((ull)candidates[i].div_count + (ull)candidates[j].div_count <= best_union) break;
ull gcd_d = calc_gcd_divisors_fast(candidates[i], candidates[j]);
ull union_size = (ull)candidates[i].div_count + (ull)candidates[j].div_count - gcd_d;
if (union_size > best_union) {
best_union = union_size;
best_x = candidates[i].val;
best_y = candidates[j].val;
}
}
}
std::cout << best_union << "\n";
std::cout << best_x << " " << best_y << "\n";
return 0;
}