import java.io.*;
import java.util.*;

public class Main {
	static long X, ans;
	static List<Long> list;

	public static long pow(long x, int y) {
		long res = 1;
		for (int i = 0; i < y; i++) {
			res *= x;
		}
		return res;
	}

	public static void solve(int idx, long val) {
		if (idx == list.size()) {
			ans = Math.min(ans, Math.max(val, X / val));
			return;
		}
		solve(idx + 1, val * list.get(idx));
		solve(idx + 1, val);
	}

	public static void main(String[] args) {
		InputReader in = new InputReader();

		boolean[] isPrime = new boolean[1000001];
		Arrays.fill(isPrime, true);
		isPrime[0] = isPrime[1] = false;
		for (int i = 2; i * i < isPrime.length; i++) {
			if (isPrime[i]) {
				for (int j = i * i; j < isPrime.length; j += i) {
					isPrime[j] = false;
				}
			}
		}
		List<Integer> prime = new ArrayList<>();
		for (int i = 2; i < isPrime.length; i++) {
			if (isPrime[i]) {
				prime.add(i);
			}
		}

		X = Long.parseLong(in.next());
		Map<Long, Integer> map = new TreeMap<>();
		long Y = X;
		for (long x : prime) {
			int cnt = 0;
			while (Y % x == 0) {
				Y /= x;
				cnt++;
			}
			if (cnt > 0) {
				map.put(x, cnt);
			}
		}
		if (Y > 1) {
			map.put(Y, 1);
		}

		list = new ArrayList<>();
		for (Map.Entry<Long, Integer> entry : map.entrySet()) {
			list.add(pow(entry.getKey(), entry.getValue()));
		}

		ans = Long.MAX_VALUE;
		solve(0, 1);

		System.out.println(X / ans + " " + ans);
	}

	static class InputReader {
		public BufferedReader reader;
		public StringTokenizer st;

		public InputReader() {
			reader = new BufferedReader(new InputStreamReader(System.in));
		}

		public String next() {
			while (st == null || !st.hasMoreTokens()) {
				st = new StringTokenizer(nextLine());
			}
			return st.nextToken();
		}

		public String nextLine() {
			try {
				return reader.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return null;
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}
	}
}