#include <iostream>

using namespace std;

// Tablica początkowych liczb pierwszych.
// Taka ilość wystarczy nawet dla N rzędu 10^18.
int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53};

long long n;
long long best_num = 1;
long long max_div = 1;

// Funkcja rekurencyjna generująca kandydatów na liczby antypierwsze
void dfs(int prime_idx, long long current_num, long long current_div, int max_exp) {
    
    // Jeśli znaleziona liczba ma więcej dzielników, staje się nowym kandydatem
    if (current_div > max_div) {
        max_div = current_div;
        best_num = current_num;
    } 
    // Jeśli ma tyle samo dzielników, wybieramy mniejszą (wynika to z definicji)
    else if (current_div == max_div && current_num < best_num) {
        best_num = current_num;
    }

    // Warunek zakończenia, by nie wyjść poza zakres tablicy primes
    if (prime_idx >= 16) return;

    long long temp_num = current_num;
    
    // Zwiększamy potęgę dla aktualnej liczby pierwszej
    // Zgodnie z własnością liczb antypierwszych i <= max_exp
    for (int i = 1; i <= max_exp; ++i) {
        
        // Zabezpieczenie przed przekroczeniem limitu n oraz przed przepełnieniem zmiennej (overflow)
        if (n / primes[prime_idx] < temp_num) {
            break; 
        }
        
        temp_num *= primes[prime_idx];
        
        // Wywołanie rekurencyjne dla kolejnej liczby pierwszej
        // Liczba dzielników po domnożeniu p^i wzrasta (i+1) razy
        dfs(prime_idx + 1, temp_num, current_div * (i + 1), i);
    }
}

int main() {
    // Optymalizacja wejścia/wyjścia
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    if (cin >> n) {
        // Zaczynamy od indeksu 0 (liczba pierwsza 2), wartości 1, 1 dzielnika 
        // i arbitralnie dużego limitu wykładnika potęgi (np. 60 dla N <= 10^18)
        dfs(0, 1, 1, 60);
        
        cout << best_num << "\n";
    }
    
    return 0;
}