#include <bits/stdc++.h> #include <chrono> #include <random> using namespace std; #define intL unsigned __int128 void print128(intL n) { if (n == 0) { cout << 0; return; } string s = ""; while (n > 0) { s += (char)('0' + (n % 10)); n /= 10; } reverse(s.begin(), s.end()); cout << s; } intL gcd(intL a, intL b) { while (b) { intL temp = b; b = a % b; a = temp; } return a; } intL mul(intL a, intL b, intL MOD) { return (intL)(((unsigned __int128)a * b) % MOD); } intL power(intL base, intL exp, intL mod) { intL res = 1; base %= mod; while (exp > 0) { if (exp % 2 == 1) res = mul(res, base, mod); base = mul(base, base, mod); exp /= 2; } return res; } bool miller_rabin(intL n) { if (n < 2) return false; if (n == 2 || n == 3) return true; if (n % 2 == 0 || n % 3 == 0) return false; intL d = n - 1; int s = 0; while (d % 2 == 0) { d /= 2; s++; } static const unsigned long long bases[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}; for (unsigned long long a : bases) { if (n <= a) break; intL x = power(a, d, n); if (x == 1 || x == n - 1) continue; bool composite = true; for (int r = 1; r < s; r++) { x = mul(x, x, n); if (x == n - 1) { composite = false; break; } } if (composite) return false; } return true; } const int MAXS = 1000000; int spf[MAXS >> 1]; int get_spf(int s) { if (!(s & 1)) return 2; int idx = s >> 1; return spf[idx] == -1 ? s : spf[idx]; } intL brent(intL N) { if (N % 2 == 0) return 2; if (N % 3 == 0) return 3; mt19937_64 rng(1337); uniform_int_distribution<long long> seed(1, N - 1); intL y = seed(rng), c = seed(rng), m = seed(rng) % (N - 1) + 1, g = 1, r = 1, q = 1, x = y, ys = y; int iterations = 0; while (g == 1 && iterations < 500000) { x = y; for (long long i = 0; i < r; ++i) { y = (mul(y, y, N) + c) % N; } intL k = 0; while (k < r && g == 1) { ys = y; intL lim = min(m, r - k); for (intL i = 0; i < lim; ++i) { y = (mul(y, y, N) + c) % N; intL diff = x > y ? x - y : y - x; q = mul(q, diff, N); } g = gcd(q, N); k += m; iterations += lim; } r <<= 1; } if (g == N || g == 1) return 0; return g; } intL squfof(intL N) { if (N % 2 == 0) return 2; unsigned long long n = (unsigned long long)N; unsigned long long root = sqrt(n); if (root * root == n) return root; auto scaled_squfof = [&](unsigned long long multiplier) { unsigned long long nn = n * multiplier; unsigned long long p0 = sqrt(nn); unsigned long long q0 = 1; unsigned long long p = p0; unsigned long long q = nn - p0 * p0; if (q == 0) return (unsigned long long)1; unsigned long long b0 = (p0 + p) / q; unsigned long long b = b0; unsigned long long l1 = 2 * b0, l2 = 1; unsigned long long i = 0; vector<unsigned long long> saved; while (i < 300000) { unsigned long long prev_q = q0; q0 = q; p = b * q0 - p; q = prev_q + b * (p0 - p); if (q == 0) break; b = (p0 + p) / q; if (i % 2 == 1) { unsigned long long root_q = sqrt(q); if (root_q * root_q == q) { saved.push_back(root_q); } } i++; } return (unsigned long long)0; }; static const unsigned long long multipliers[] = {1, 3, 5, 7, 11, 13, 17, 19, 23}; for (auto mult : multipliers) { if (__int128(n) * mult > ~((unsigned long long)0)) continue; unsigned long long f = scaled_squfof(mult); if (f > 1 && f < n) { intL g = gcd(f, N); if (g > 1 && g < N) return g; } } return 0; } void factorize(intL N, map<intL, intL> &mp) { if (N == 1) return; if (N < MAXS) { while (N > 1) { int p = get_spf(N); while (N % p == 0) { ++mp[p]; N /= p; } } return; } for (intL p = 2; p * p <= N && p < MAXS; ++p) { while (N % p == 0) { ++mp[p]; N /= p; } } if (N == 1) return; if (miller_rabin(N)) { ++mp[N]; return; } intL Q = brent(N); if (Q == 0 || Q == 1 || Q == N) { Q = squfof(N); } if (Q == 0 || Q == 1 || Q == N) { ++mp[N]; return; } factorize(Q, mp); factorize(N / Q, mp); } signed main() { ios::sync_with_stdio(false); cin.tie(0); fill(spf, spf + (MAXS >> 1), -1); for (int i = 3; i * i <= MAXS; i += 2) { if (spf[i >> 1] == -1) { for (int j = i * i; j <= MAXS; j += (i << 1)) if (spf[j >> 1] == -1) spf[j >> 1] = i; } } string s; while (cin >> s && s != "0") { intL N = 0; for (char ch : s) N = N * 10 + (ch - '0'); map<intL, intL> mp; factorize(N, mp); for (auto const &[prime, exp] : mp) { print128(prime); cout << "^"; print128(exp); cout << " "; } cout << "\n"; } return 0; }