// need
#include <iostream>
#include <algorithm>

// data structure
#include <bitset>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <complex>
//#include <deque>
#include <valarray>
#include <array>
#include <unordered_map>

// stream
//#include <istream>
//#include <sstream>
//#include <ostream>
#include <fstream>

// etc
#include <cassert>
#include <cmath>
#include <functional>
#include <iomanip>
#include <chrono>
#include <random>
#include <numeric>

// input
#define INIT std::ios::sync_with_stdio(false);std::cin.tie(0);
#define VAR(type, ...)type __VA_ARGS__;MACRO_VAR_Scan(__VA_ARGS__);
template<typename T> void MACRO_VAR_Scan(T& t) { std::cin >> t; }
template<typename First, typename...Rest>void MACRO_VAR_Scan(First& first, Rest&...rest) { std::cin >> first; MACRO_VAR_Scan(rest...); }
#define VEC_ROW(type, n, ...)std::vector<type> __VA_ARGS__;MACRO_VEC_ROW_Init(n, __VA_ARGS__); for(int i=0; i<n; ++i){MACRO_VEC_ROW_Scan(i, __VA_ARGS__);}
template<typename T> void MACRO_VEC_ROW_Init(int n, T& t) { t.resize(n); }
template<typename First, typename...Rest>void MACRO_VEC_ROW_Init(int n, First& first, Rest&...rest) { first.resize(n); MACRO_VEC_ROW_Init(n, rest...); }
template<typename T> void MACRO_VEC_ROW_Scan(int p, T& t) { std::cin >> t[p]; }
template<typename First, typename...Rest>void MACRO_VEC_ROW_Scan(int p, First& first, Rest&...rest) { std::cin >> first[p]; MACRO_VEC_ROW_Scan(p, rest...); }
#define VEC(type, c, n) std::vector<type> c(n);for(auto& i:c)std::cin>>i;
#define MAT(type, c, m, n) std::vector<std::vector<type>> c(m, std::vector<type>(n));for(auto& r:c)for(auto& i:r)std::cin>>i;

// output
#define OUT(d) std::cout<<(d);
#define FOUT(n, d) std::cout<<std::fixed<<std::setprecision(n)<<(d);
#define SOUT(n, c, d) std::cout<<std::setw(n)<<std::setfill(c)<<(d);
#define SP std::cout<<" ";
#define TAB std::cout<<"\t";
#define BR std::cout<<"\n";
#define SPBR(i, n) std::cout<<(i + 1 == n ? '\n' : ' ');
#define ENDL std::cout<<std::endl;
#define FLUSH std::cout<<std::flush;
#define SHOW(d) {std::cerr << #d << "\t:" << (d) << "\n";}
#define SHOWVECTOR(v) {std::cerr << #v << "\t:";for(const auto& xxx : v){std::cerr << xxx << " ";}std::cerr << "\n";}
#define SHOWVECTOR2(v) {std::cerr << #v << "\t:\n";for(const auto& xxx : v){for(const auto& yyy : xxx){std::cerr << yyy << " ";}std::cerr << "\n";}}
#define SHOWQUEUE(a) {auto tmp(a);std::cerr << #a << "\t:";while(!tmp.empty()){std::cerr << tmp.front() << " ";tmp.pop();}std::cerr << "\n";}

// utility
#define ALL(a) (a).begin(),(a).end()
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define RFOR(i, a, b) for(int i=(b)-1;i>=(a);--i)
#define REP(i, n) for(int i=0;i<int(n);++i)
#define RREP(i, n) for(int i=int(n)-1;i>=0;--i)
#define FORLL(i, a, b) for(ll i=ll(a);i<ll(b);++i)
#define RFORLL(i, a, b) for(ll i=ll(b)-1;i>=ll(a);--i)
#define REPLL(i, n) for(ll i=0;i<ll(n);++i)
#define RREPLL(i, n) for(ll i=ll(n)-1;i>=0;--i)
#define IN(a, x, b) (a<=x && x<b)
template<typename T> inline T CHMAX(T& a, const T b) { return a = (a < b) ? b : a; }
template<typename T> inline T CHMIN(T& a, const T b) { return a = (a > b) ? b : a; }
#define EXCEPTION(msg) throw std::string("Exception : " msg " [ in ") + __func__ + " : " + std::to_string(__LINE__) + " lines ]"
#define TRY(cond, msg) try {if (cond) EXCEPTION(msg);}catch (std::string s) {std::cerr << s << std::endl;}
void CHECKTIME(std::function<void()> f) { auto start = std::chrono::system_clock::now(); f(); auto end = std::chrono::system_clock::now(); auto res = std::chrono::duration_cast<std::chrono::nanoseconds>((end - start)).count(); std::cerr << "[Time:" << res << "ns  (" << res / (1.0e9) << "s)]\n"; }

// test
template<class T> std::vector<std::vector<T>> VV(int n, int m, T init = T()) {
	return std::vector<std::vector<T>>(n, std::vector<T>(m, init));
}
template<typename S, typename T>
std::ostream& operator<<(std::ostream& os, std::pair<S, T> p) {
	os << "(" << p.first << ", " << p.second << ")"; return os;
}

// type/const
#define int ll
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using PAIR = std::pair<int, int>;
using PAIRLL = std::pair<ll, ll>;
constexpr int INFINT = 1 << 30;                          // 1.07x10^ 9
constexpr int INFINT_LIM = (1LL << 31) - 1;              // 2.15x10^ 9
constexpr ll INFLL = 1LL << 60;                          // 1.15x10^18
constexpr ll INFLL_LIM = (1LL << 62) - 1 + (1LL << 62);  // 9.22x10^18
constexpr double EPS = 1e-9;
constexpr int MOD = 1000000007;
constexpr double PI = 3.141592653589793238462643383279;

template<class T, size_t N> void FILL(T(&a)[N], const T& val) { for (auto& x : a) x = val; }
template<class ARY, size_t N, size_t M, class T> void FILL(ARY(&a)[N][M], const T& val) { for (auto& b : a) FILL(b, val); }
template<class T> void FILL(std::vector<T>& a, const T& val) { for (auto& x : a) x = val; }
template<class ARY, class T> void FILL(std::vector<std::vector<ARY>>& a, const T& val) { for (auto& b : a) FILL(b, val); }

// ------------>8------------------------------------->8------------

std::map<int, std::string> map;
void update(int x, std::string s) {
	auto it = map.find(x);
	if (it == map.end() || it->second.size() > s.size()) {
		map[x] = s;
	}
}

signed main() {
	INIT;

	VAR(int, n);

	std::vector<std::string> ts(100000);
	REP(i, ts.size()) ts[i] = std::to_string(i);

	update(1, "1");
	FOR(i, 2, 100000) {
		std::string s = ts[i];
		update(i, s);
		s += '^';

		int j = 2;
		int now = i * i;
		while (now <= n) {
			update(now, s + ts[j]);
			now *= i;
			++j;
		}
	}
	FOR(i, 2, 100) FOR(j, i, 100) update(i * j, ts[i] + '*' + ts[j]);

	std::string anss(std::to_string(n));
	int ans = anss.size();

	auto ansupd = [&](std::string s) {
		if (ans > s.size()) {
			anss = s;
			ans = s.size();
		}
	};

	{
		if (map.count(n)) ansupd(map[n]);
	}

	for (int i = 2; i * i <= n; ++i) {
		int t = n / i;
		int r = n - i * t;
		std::string s;
		s += map.count(i) ? map[i] : std::to_string(i);
		s += "*";
		s += map.count(t) ? map[t] : std::to_string(t);
		if (r) {
			s += "+";
			s += map.count(r) ? map[r] : std::to_string(r);
		}
		ansupd(s);
	}

	for (auto& p : map) {
		auto calc = [&](int x, std::string s) {
			auto it = std::prev(map.upper_bound(n - x));
			if (it == map.end()) return;
			if (s.size() + 1 + it->second.size() >= ans) return;

			std::string ss(s + "+" + it->second);
			if (x + it->first == n) {
				ansupd(ss);
			}
			else {
				if (ss.size() + 2 >= ans) return;
				int r = n - x - it->first;
				ss += "+";
				ss += map.count(r) ? map[r] : std::to_string(r);
				ansupd(ss);
			}
		};

		if (p.second.size() >= ans) continue;
		calc(p.first, p.second);
		FOR(i, 2, 100) {
			if (p.second.size() + 1 + ts[i].size() >= ans) continue;
			if (p.first * i > n) break;
			calc(p.first * i, ts[i] + "*" + p.second);
		}
	}

	OUT(anss)BR;

	return 0;
}


// need
#include <iostream>
#include <algorithm>

// data structure
#include <bitset>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <complex>
//#include <deque>
#include <valarray>
#include <array>
#include <unordered_map>

// stream
//#include <istream>
//#include <sstream>
//#include <ostream>
#include <fstream>

// etc
#include <cassert>
#include <cmath>
#include <functional>
#include <iomanip>
#include <chrono>
#include <random>
#include <numeric>

// input
#define INIT std::ios::sync_with_stdio(false);std::cin.tie(0);
#define VAR(type, ...)type __VA_ARGS__;MACRO_VAR_Scan(__VA_ARGS__);
template<typename T> void MACRO_VAR_Scan(T& t) { std::cin >> t; }
template<typename First, typename...Rest>void MACRO_VAR_Scan(First& first, Rest&...rest) { std::cin >> first; MACRO_VAR_Scan(rest...); }
#define VEC_ROW(type, n, ...)std::vector<type> __VA_ARGS__;MACRO_VEC_ROW_Init(n, __VA_ARGS__); for(int i=0; i<n; ++i){MACRO_VEC_ROW_Scan(i, __VA_ARGS__);}
template<typename T> void MACRO_VEC_ROW_Init(int n, T& t) { t.resize(n); }
template<typename First, typename...Rest>void MACRO_VEC_ROW_Init(int n, First& first, Rest&...rest) { first.resize(n); MACRO_VEC_ROW_Init(n, rest...); }
template<typename T> void MACRO_VEC_ROW_Scan(int p, T& t) { std::cin >> t[p]; }
template<typename First, typename...Rest>void MACRO_VEC_ROW_Scan(int p, First& first, Rest&...rest) { std::cin >> first[p]; MACRO_VEC_ROW_Scan(p, rest...); }
#define VEC(type, c, n) std::vector<type> c(n);for(auto& i:c)std::cin>>i;
#define MAT(type, c, m, n) std::vector<std::vector<type>> c(m, std::vector<type>(n));for(auto& r:c)for(auto& i:r)std::cin>>i;

// output
#define OUT(d) std::cout<<(d);
#define FOUT(n, d) std::cout<<std::fixed<<std::setprecision(n)<<(d);
#define SOUT(n, c, d) std::cout<<std::setw(n)<<std::setfill(c)<<(d);
#define SP std::cout<<" ";
#define TAB std::cout<<"\t";
#define BR std::cout<<"\n";
#define SPBR(i, n) std::cout<<(i + 1 == n ? '\n' : ' ');
#define ENDL std::cout<<std::endl;
#define FLUSH std::cout<<std::flush;
#define SHOW(d) {std::cerr << #d << "\t:" << (d) << "\n";}
#define SHOWVECTOR(v) {std::cerr << #v << "\t:";for(const auto& xxx : v){std::cerr << xxx << " ";}std::cerr << "\n";}
#define SHOWVECTOR2(v) {std::cerr << #v << "\t:\n";for(const auto& xxx : v){for(const auto& yyy : xxx){std::cerr << yyy << " ";}std::cerr << "\n";}}
#define SHOWQUEUE(a) {auto tmp(a);std::cerr << #a << "\t:";while(!tmp.empty()){std::cerr << tmp.front() << " ";tmp.pop();}std::cerr << "\n";}

// utility
#define ALL(a) (a).begin(),(a).end()
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define RFOR(i, a, b) for(int i=(b)-1;i>=(a);--i)
#define REP(i, n) for(int i=0;i<int(n);++i)
#define RREP(i, n) for(int i=int(n)-1;i>=0;--i)
#define FORLL(i, a, b) for(ll i=ll(a);i<ll(b);++i)
#define RFORLL(i, a, b) for(ll i=ll(b)-1;i>=ll(a);--i)
#define REPLL(i, n) for(ll i=0;i<ll(n);++i)
#define RREPLL(i, n) for(ll i=ll(n)-1;i>=0;--i)
#define IN(a, x, b) (a<=x && x<b)
template<typename T> inline T CHMAX(T& a, const T b) { return a = (a < b) ? b : a; }
template<typename T> inline T CHMIN(T& a, const T b) { return a = (a > b) ? b : a; }
#define EXCEPTION(msg) throw std::string("Exception : " msg " [ in ") + __func__ + " : " + std::to_string(__LINE__) + " lines ]"
#define TRY(cond, msg) try {if (cond) EXCEPTION(msg);}catch (std::string s) {std::cerr << s << std::endl;}
void CHECKTIME(std::function<void()> f) { auto start = std::chrono::system_clock::now(); f(); auto end = std::chrono::system_clock::now(); auto res = std::chrono::duration_cast<std::chrono::nanoseconds>((end - start)).count(); std::cerr << "[Time:" << res << "ns  (" << res / (1.0e9) << "s)]\n"; }

// test
template<class T> std::vector<std::vector<T>> VV(int n, int m, T init = T()) {
	return std::vector<std::vector<T>>(n, std::vector<T>(m, init));
}
template<typename S, typename T>
std::ostream& operator<<(std::ostream& os, std::pair<S, T> p) {
	os << "(" << p.first << ", " << p.second << ")"; return os;
}

// type/const
#define int ll
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using PAIR = std::pair<int, int>;
using PAIRLL = std::pair<ll, ll>;
constexpr int INFINT = 1 << 30;                          // 1.07x10^ 9
constexpr int INFINT_LIM = (1LL << 31) - 1;              // 2.15x10^ 9
constexpr ll INFLL = 1LL << 60;                          // 1.15x10^18
constexpr ll INFLL_LIM = (1LL << 62) - 1 + (1LL << 62);  // 9.22x10^18
constexpr double EPS = 1e-9;
constexpr int MOD = 1000000007;
constexpr double PI = 3.141592653589793238462643383279;

template<class T, size_t N> void FILL(T(&a)[N], const T& val) { for (auto& x : a) x = val; }
template<class ARY, size_t N, size_t M, class T> void FILL(ARY(&a)[N][M], const T& val) { for (auto& b : a) FILL(b, val); }
template<class T> void FILL(std::vector<T>& a, const T& val) { for (auto& x : a) x = val; }
template<class ARY, class T> void FILL(std::vector<std::vector<ARY>>& a, const T& val) { for (auto& b : a) FILL(b, val); }

// ------------>8------------------------------------->8------------

std::map<int, std::string> map;
void update(int x, std::string s) {
	auto it = map.find(x);
	if (it == map.end() || it->second.size() > s.size()) {
		map[x] = s;
	}
}

signed main() {
	INIT;

	VAR(int, n);

	std::vector<std::string> ts(10000);
	REP(i, ts.size()) ts[i] = std::to_string(i);

	update(1, "1");
	FOR(i, 2, 10000) {
		std::string s = ts[i];
		update(i, s);
		s += '^';

		int j = 2;
		int now = i * i;
		while (now <= n) {
			update(now, s + ts[j]);
			now *= i;
			++j;
		}
	}
	FOR(i, 2, 100) FOR(j, i, 100) update(i * j, ts[i] + '*' + ts[j]);

	std::string anss(std::to_string(n));
	int ans = anss.size();

	auto ansupd = [&](std::string s) {
		if (ans > s.size()) {
			anss = s;
			ans = s.size();
		}
	};

	{
		if (map.count(n)) ansupd(map[n]);
	}

	for (int i = 2; i * i <= n; ++i) {
		int t = n / i;
		int r = n - i * t;
		std::string s;
		s += map.count(i) ? map[i] : std::to_string(i);
		s += "*";
		s += map.count(t) ? map[t] : std::to_string(t);
		if (r) {
			s += "+";
			s += map.count(r) ? map[r] : std::to_string(r);
		}
		ansupd(s);
	}

	for (auto& p : map) {
		auto calc = [&](int x, std::string s) {
			auto it = std::prev(map.upper_bound(n - x));
			if (it == map.end()) return;
			if (s.size() + 1 + it->second.size() >= ans) return;

			std::string ss(s + "+" + it->second);
			if (x + it->first == n) {
				ansupd(ss);
			}
			else {
				if (ss.size() + 2 >= ans) return;
				int r = n - x - it->first;
				ss += "+";
				ss += map.count(r) ? map[r] : std::to_string(r);
				ansupd(ss);
			}
		};

		calc(p.first, p.second);
		FOR(i, 2, 100) {
			if (p.first * i > n) break;
			calc(p.first * i, ts[i] + "*" + p.second);
		}
	}

	OUT(anss)BR;

	return 0;
}


// need
#include <iostream>
#include <algorithm>

// data structure
#include <bitset>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <complex>
//#include <deque>
#include <valarray>
#include <array>
#include <unordered_map>

// stream
//#include <istream>
//#include <sstream>
//#include <ostream>
#include <fstream>

// etc
#include <cassert>
#include <cmath>
#include <functional>
#include <iomanip>
#include <chrono>
#include <random>
#include <numeric>

// input
#define INIT std::ios::sync_with_stdio(false);std::cin.tie(0);
#define VAR(type, ...)type __VA_ARGS__;MACRO_VAR_Scan(__VA_ARGS__);
template<typename T> void MACRO_VAR_Scan(T& t) { std::cin >> t; }
template<typename First, typename...Rest>void MACRO_VAR_Scan(First& first, Rest&...rest) { std::cin >> first; MACRO_VAR_Scan(rest...); }
#define VEC_ROW(type, n, ...)std::vector<type> __VA_ARGS__;MACRO_VEC_ROW_Init(n, __VA_ARGS__); for(int i=0; i<n; ++i){MACRO_VEC_ROW_Scan(i, __VA_ARGS__);}
template<typename T> void MACRO_VEC_ROW_Init(int n, T& t) { t.resize(n); }
template<typename First, typename...Rest>void MACRO_VEC_ROW_Init(int n, First& first, Rest&...rest) { first.resize(n); MACRO_VEC_ROW_Init(n, rest...); }
template<typename T> void MACRO_VEC_ROW_Scan(int p, T& t) { std::cin >> t[p]; }
template<typename First, typename...Rest>void MACRO_VEC_ROW_Scan(int p, First& first, Rest&...rest) { std::cin >> first[p]; MACRO_VEC_ROW_Scan(p, rest...); }
#define VEC(type, c, n) std::vector<type> c(n);for(auto& i:c)std::cin>>i;
#define MAT(type, c, m, n) std::vector<std::vector<type>> c(m, std::vector<type>(n));for(auto& r:c)for(auto& i:r)std::cin>>i;

// output
#define OUT(d) std::cout<<(d);
#define FOUT(n, d) std::cout<<std::fixed<<std::setprecision(n)<<(d);
#define SOUT(n, c, d) std::cout<<std::setw(n)<<std::setfill(c)<<(d);
#define SP std::cout<<" ";
#define TAB std::cout<<"\t";
#define BR std::cout<<"\n";
#define SPBR(i, n) std::cout<<(i + 1 == n ? '\n' : ' ');
#define ENDL std::cout<<std::endl;
#define FLUSH std::cout<<std::flush;
#define SHOW(d) {std::cerr << #d << "\t:" << (d) << "\n";}
#define SHOWVECTOR(v) {std::cerr << #v << "\t:";for(const auto& xxx : v){std::cerr << xxx << " ";}std::cerr << "\n";}
#define SHOWVECTOR2(v) {std::cerr << #v << "\t:\n";for(const auto& xxx : v){for(const auto& yyy : xxx){std::cerr << yyy << " ";}std::cerr << "\n";}}
#define SHOWQUEUE(a) {auto tmp(a);std::cerr << #a << "\t:";while(!tmp.empty()){std::cerr << tmp.front() << " ";tmp.pop();}std::cerr << "\n";}

// utility
#define ALL(a) (a).begin(),(a).end()
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define RFOR(i, a, b) for(int i=(b)-1;i>=(a);--i)
#define REP(i, n) for(int i=0;i<int(n);++i)
#define RREP(i, n) for(int i=int(n)-1;i>=0;--i)
#define FORLL(i, a, b) for(ll i=ll(a);i<ll(b);++i)
#define RFORLL(i, a, b) for(ll i=ll(b)-1;i>=ll(a);--i)
#define REPLL(i, n) for(ll i=0;i<ll(n);++i)
#define RREPLL(i, n) for(ll i=ll(n)-1;i>=0;--i)
#define IN(a, x, b) (a<=x && x<b)
template<typename T> inline T CHMAX(T& a, const T b) { return a = (a < b) ? b : a; }
template<typename T> inline T CHMIN(T& a, const T b) { return a = (a > b) ? b : a; }
#define EXCEPTION(msg) throw std::string("Exception : " msg " [ in ") + __func__ + " : " + std::to_string(__LINE__) + " lines ]"
#define TRY(cond, msg) try {if (cond) EXCEPTION(msg);}catch (std::string s) {std::cerr << s << std::endl;}
void CHECKTIME(std::function<void()> f) { auto start = std::chrono::system_clock::now(); f(); auto end = std::chrono::system_clock::now(); auto res = std::chrono::duration_cast<std::chrono::nanoseconds>((end - start)).count(); std::cerr << "[Time:" << res << "ns  (" << res / (1.0e9) << "s)]\n"; }

// test
template<class T> std::vector<std::vector<T>> VV(int n, int m, T init = T()) {
	return std::vector<std::vector<T>>(n, std::vector<T>(m, init));
}
template<typename S, typename T>
std::ostream& operator<<(std::ostream& os, std::pair<S, T> p) {
	os << "(" << p.first << ", " << p.second << ")"; return os;
}

// type/const
#define int ll
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using PAIR = std::pair<int, int>;
using PAIRLL = std::pair<ll, ll>;
constexpr int INFINT = 1 << 30;                          // 1.07x10^ 9
constexpr int INFINT_LIM = (1LL << 31) - 1;              // 2.15x10^ 9
constexpr ll INFLL = 1LL << 60;                          // 1.15x10^18
constexpr ll INFLL_LIM = (1LL << 62) - 1 + (1LL << 62);  // 9.22x10^18
constexpr double EPS = 1e-9;
constexpr int MOD = 1000000007;
constexpr double PI = 3.141592653589793238462643383279;

template<class T, size_t N> void FILL(T(&a)[N], const T& val) { for (auto& x : a) x = val; }
template<class ARY, size_t N, size_t M, class T> void FILL(ARY(&a)[N][M], const T& val) { for (auto& b : a) FILL(b, val); }
template<class T> void FILL(std::vector<T>& a, const T& val) { for (auto& x : a) x = val; }
template<class ARY, class T> void FILL(std::vector<std::vector<ARY>>& a, const T& val) { for (auto& b : a) FILL(b, val); }

// ------------>8------------------------------------->8------------

std::map<int, std::string> map;
void update(int x, std::string s) {
	auto it = map.find(x);
	if (it == map.end() || it->second.size() > s.size()) {
		map[x] = s;
	}
}

signed main() {
	INIT;

	VAR(int, n);

	std::vector<std::string> ts(100000);
	REP(i, ts.size()) ts[i] = std::to_string(i);

	update(1, "1");
	FOR(i, 2, 100000) {
		std::string s = ts[i];
		update(i, s);
		s += '^';

		int j = 2;
		int now = i * i;
		while (now <= n) {
			update(now, s + ts[j]);
			now *= i;
			++j;
		}
	}
	FOR(i, 2, 100) FOR(j, i, 100) update(i * j, ts[i] + '*' + ts[j]);

	std::string anss(std::to_string(n));
	int ans = anss.size();

	auto ansupd = [&](std::string s) {
		if (ans > s.size()) {
			anss = s;
			ans = s.size();
		}
	};

	{
		if (map.count(n)) ansupd(map[n]);
	}

	for (int i = 2; i * i <= n; ++i) {
		int t = n / i;
		int r = n - i * t;
		std::string s;
		s += map.count(i) ? map[i] : std::to_string(i);
		s += "*";
		s += map.count(t) ? map[t] : std::to_string(t);
		if (r) {
			s += "+";
			s += map.count(r) ? map[r] : std::to_string(r);
		}
		ansupd(s);
	}

	for (auto& p : map) {
		auto calc = [&](int x, std::string s) {
			auto it = std::prev(map.upper_bound(n - x));
			if (it == map.end()) return;
			if (s.size() + 1 + it->second.size() >= ans) return;

			std::string ss(s + "+" + it->second);
			if (x + it->first == n) {
				ansupd(ss);
			}
			else {
				if (ss.size() + 2 >= ans) return;
				int r = n - x - it->first;
				ss += map.count(r) ? map[r] : std::to_string(r);
				ansupd(ss);
			}
		};

		calc(p.first, p.second);
		FOR(i, 2, 100) {
			if (p.first * i > n) break;
			calc(p.first * i, ts[i] + "*" + p.second);
		}
	}

	OUT(anss)BR;

	return 0;
}


// need
#include <iostream>
#include <algorithm>

// data structure
#include <bitset>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <complex>
//#include <deque>
#include <valarray>
#include <array>
#include <unordered_map>

// stream
//#include <istream>
//#include <sstream>
//#include <ostream>
#include <fstream>

// etc
#include <cassert>
#include <cmath>
#include <functional>
#include <iomanip>
#include <chrono>
#include <random>
#include <numeric>

// input
#define INIT std::ios::sync_with_stdio(false);std::cin.tie(0);
#define VAR(type, ...)type __VA_ARGS__;MACRO_VAR_Scan(__VA_ARGS__);
template<typename T> void MACRO_VAR_Scan(T& t) { std::cin >> t; }
template<typename First, typename...Rest>void MACRO_VAR_Scan(First& first, Rest&...rest) { std::cin >> first; MACRO_VAR_Scan(rest...); }
#define VEC_ROW(type, n, ...)std::vector<type> __VA_ARGS__;MACRO_VEC_ROW_Init(n, __VA_ARGS__); for(int i=0; i<n; ++i){MACRO_VEC_ROW_Scan(i, __VA_ARGS__);}
template<typename T> void MACRO_VEC_ROW_Init(int n, T& t) { t.resize(n); }
template<typename First, typename...Rest>void MACRO_VEC_ROW_Init(int n, First& first, Rest&...rest) { first.resize(n); MACRO_VEC_ROW_Init(n, rest...); }
template<typename T> void MACRO_VEC_ROW_Scan(int p, T& t) { std::cin >> t[p]; }
template<typename First, typename...Rest>void MACRO_VEC_ROW_Scan(int p, First& first, Rest&...rest) { std::cin >> first[p]; MACRO_VEC_ROW_Scan(p, rest...); }
#define VEC(type, c, n) std::vector<type> c(n);for(auto& i:c)std::cin>>i;
#define MAT(type, c, m, n) std::vector<std::vector<type>> c(m, std::vector<type>(n));for(auto& r:c)for(auto& i:r)std::cin>>i;

// output
#define OUT(d) std::cout<<(d);
#define FOUT(n, d) std::cout<<std::fixed<<std::setprecision(n)<<(d);
#define SOUT(n, c, d) std::cout<<std::setw(n)<<std::setfill(c)<<(d);
#define SP std::cout<<" ";
#define TAB std::cout<<"\t";
#define BR std::cout<<"\n";
#define SPBR(i, n) std::cout<<(i + 1 == n ? '\n' : ' ');
#define ENDL std::cout<<std::endl;
#define FLUSH std::cout<<std::flush;
#define SHOW(d) {std::cerr << #d << "\t:" << (d) << "\n";}
#define SHOWVECTOR(v) {std::cerr << #v << "\t:";for(const auto& xxx : v){std::cerr << xxx << " ";}std::cerr << "\n";}
#define SHOWVECTOR2(v) {std::cerr << #v << "\t:\n";for(const auto& xxx : v){for(const auto& yyy : xxx){std::cerr << yyy << " ";}std::cerr << "\n";}}
#define SHOWQUEUE(a) {auto tmp(a);std::cerr << #a << "\t:";while(!tmp.empty()){std::cerr << tmp.front() << " ";tmp.pop();}std::cerr << "\n";}

// utility
#define ALL(a) (a).begin(),(a).end()
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define RFOR(i, a, b) for(int i=(b)-1;i>=(a);--i)
#define REP(i, n) for(int i=0;i<int(n);++i)
#define RREP(i, n) for(int i=int(n)-1;i>=0;--i)
#define FORLL(i, a, b) for(ll i=ll(a);i<ll(b);++i)
#define RFORLL(i, a, b) for(ll i=ll(b)-1;i>=ll(a);--i)
#define REPLL(i, n) for(ll i=0;i<ll(n);++i)
#define RREPLL(i, n) for(ll i=ll(n)-1;i>=0;--i)
#define IN(a, x, b) (a<=x && x<b)
template<typename T> inline T CHMAX(T& a, const T b) { return a = (a < b) ? b : a; }
template<typename T> inline T CHMIN(T& a, const T b) { return a = (a > b) ? b : a; }
#define EXCEPTION(msg) throw std::string("Exception : " msg " [ in ") + __func__ + " : " + std::to_string(__LINE__) + " lines ]"
#define TRY(cond, msg) try {if (cond) EXCEPTION(msg);}catch (std::string s) {std::cerr << s << std::endl;}
void CHECKTIME(std::function<void()> f) { auto start = std::chrono::system_clock::now(); f(); auto end = std::chrono::system_clock::now(); auto res = std::chrono::duration_cast<std::chrono::nanoseconds>((end - start)).count(); std::cerr << "[Time:" << res << "ns  (" << res / (1.0e9) << "s)]\n"; }

// test
template<class T> std::vector<std::vector<T>> VV(int n, int m, T init = T()) {
	return std::vector<std::vector<T>>(n, std::vector<T>(m, init));
}
template<typename S, typename T>
std::ostream& operator<<(std::ostream& os, std::pair<S, T> p) {
	os << "(" << p.first << ", " << p.second << ")"; return os;
}

// type/const
#define int ll
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using PAIR = std::pair<int, int>;
using PAIRLL = std::pair<ll, ll>;
constexpr int INFINT = 1 << 30;                          // 1.07x10^ 9
constexpr int INFINT_LIM = (1LL << 31) - 1;              // 2.15x10^ 9
constexpr ll INFLL = 1LL << 60;                          // 1.15x10^18
constexpr ll INFLL_LIM = (1LL << 62) - 1 + (1LL << 62);  // 9.22x10^18
constexpr double EPS = 1e-9;
constexpr int MOD = 1000000007;
constexpr double PI = 3.141592653589793238462643383279;

template<class T, size_t N> void FILL(T(&a)[N], const T& val) { for (auto& x : a) x = val; }
template<class ARY, size_t N, size_t M, class T> void FILL(ARY(&a)[N][M], const T& val) { for (auto& b : a) FILL(b, val); }
template<class T> void FILL(std::vector<T>& a, const T& val) { for (auto& x : a) x = val; }
template<class ARY, class T> void FILL(std::vector<std::vector<ARY>>& a, const T& val) { for (auto& b : a) FILL(b, val); }

// ------------>8------------------------------------->8------------

std::map<int, std::string> map;
void update(int x, std::string s) {
	auto it = map.find(x);
	if (it == map.end() || it->second.size() > s.size()) {
		map[x] = s;
	}
}

signed main() {
	INIT;

	VAR(int, n);

	std::vector<std::string> ts(10000);
	REP(i, ts.size()) ts[i] = std::to_string(i);

	update(1, "1");
	FOR(i, 2, 10000) {
		std::string s = ts[i];
		update(i, s);
		s += '^';

		int j = 2;
		int now = i * i;
		while (now <= n) {
			update(now, s + ts[j]);
			now *= i;
			++j;
		}
	}
	FOR(i, 2, 100) FOR(j, i, 100) update(i * j, ts[i] + '*' + ts[j]);

	std::string anss(std::to_string(n));
	int ans = anss.size();

	auto ansupd = [&](std::string s) {
		if (ans > s.size()) {
			anss = s;
			ans = s.size();
		}
	};

	{
		if (map.count(n)) ansupd(map[n]);
	}

	for (int i = 2; i * i <= n; ++i) {
		int t = n / i;
		int r = n - i * t;
		std::string s;
		s += map.count(i) ? map[i] : std::to_string(i);
		s += "*";
		s += map.count(t) ? map[t] : std::to_string(t);
		if (r) {
			s += "+";
			s += map.count(r) ? map[r] : std::to_string(r);
		}
		ansupd(s);
	}

	for (auto& p : map) {
		auto calc = [&](int x, std::string s) {
			auto it = std::prev(map.upper_bound(n - x));
			if (it == map.end()) return;
			if (s.size() + 1 + it->second.size() >= ans) return;

			std::string ss(s + "+" + it->second);
			if (x + it->first == n) {
				ansupd(ss);
			}
			else {
				if (ss.size() + 2 >= ans) return;
				int r = n - x - it->first;
				ss += map.count(r) ? map[r] : std::to_string(r);
				ansupd(ss);
			}
		};

		calc(p.first, p.second);
		FOR(i, 2, 100) {
			if (p.first * i > n) break;
			calc(p.first * i, ts[i] + "*" + p.second);
		}
	}

	OUT(anss)BR;

	return 0;
}


// need
#include <iostream>
#include <algorithm>

// data structure
#include <bitset>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <complex>
//#include <deque>
#include <valarray>
#include <array>
#include <unordered_map>

// stream
//#include <istream>
//#include <sstream>
//#include <ostream>
#include <fstream>

// etc
#include <cassert>
#include <cmath>
#include <functional>
#include <iomanip>
#include <chrono>
#include <random>
#include <numeric>

// input
#define INIT std::ios::sync_with_stdio(false);std::cin.tie(0);
#define VAR(type, ...)type __VA_ARGS__;MACRO_VAR_Scan(__VA_ARGS__);
template<typename T> void MACRO_VAR_Scan(T& t) { std::cin >> t; }
template<typename First, typename...Rest>void MACRO_VAR_Scan(First& first, Rest&...rest) { std::cin >> first; MACRO_VAR_Scan(rest...); }
#define VEC_ROW(type, n, ...)std::vector<type> __VA_ARGS__;MACRO_VEC_ROW_Init(n, __VA_ARGS__); for(int i=0; i<n; ++i){MACRO_VEC_ROW_Scan(i, __VA_ARGS__);}
template<typename T> void MACRO_VEC_ROW_Init(int n, T& t) { t.resize(n); }
template<typename First, typename...Rest>void MACRO_VEC_ROW_Init(int n, First& first, Rest&...rest) { first.resize(n); MACRO_VEC_ROW_Init(n, rest...); }
template<typename T> void MACRO_VEC_ROW_Scan(int p, T& t) { std::cin >> t[p]; }
template<typename First, typename...Rest>void MACRO_VEC_ROW_Scan(int p, First& first, Rest&...rest) { std::cin >> first[p]; MACRO_VEC_ROW_Scan(p, rest...); }
#define VEC(type, c, n) std::vector<type> c(n);for(auto& i:c)std::cin>>i;
#define MAT(type, c, m, n) std::vector<std::vector<type>> c(m, std::vector<type>(n));for(auto& r:c)for(auto& i:r)std::cin>>i;

// output
#define OUT(d) std::cout<<(d);
#define FOUT(n, d) std::cout<<std::fixed<<std::setprecision(n)<<(d);
#define SOUT(n, c, d) std::cout<<std::setw(n)<<std::setfill(c)<<(d);
#define SP std::cout<<" ";
#define TAB std::cout<<"\t";
#define BR std::cout<<"\n";
#define SPBR(i, n) std::cout<<(i + 1 == n ? '\n' : ' ');
#define ENDL std::cout<<std::endl;
#define FLUSH std::cout<<std::flush;
#define SHOW(d) {std::cerr << #d << "\t:" << (d) << "\n";}
#define SHOWVECTOR(v) {std::cerr << #v << "\t:";for(const auto& xxx : v){std::cerr << xxx << " ";}std::cerr << "\n";}
#define SHOWVECTOR2(v) {std::cerr << #v << "\t:\n";for(const auto& xxx : v){for(const auto& yyy : xxx){std::cerr << yyy << " ";}std::cerr << "\n";}}
#define SHOWQUEUE(a) {auto tmp(a);std::cerr << #a << "\t:";while(!tmp.empty()){std::cerr << tmp.front() << " ";tmp.pop();}std::cerr << "\n";}

// utility
#define ALL(a) (a).begin(),(a).end()
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define RFOR(i, a, b) for(int i=(b)-1;i>=(a);--i)
#define REP(i, n) for(int i=0;i<int(n);++i)
#define RREP(i, n) for(int i=int(n)-1;i>=0;--i)
#define FORLL(i, a, b) for(ll i=ll(a);i<ll(b);++i)
#define RFORLL(i, a, b) for(ll i=ll(b)-1;i>=ll(a);--i)
#define REPLL(i, n) for(ll i=0;i<ll(n);++i)
#define RREPLL(i, n) for(ll i=ll(n)-1;i>=0;--i)
#define IN(a, x, b) (a<=x && x<b)
template<typename T> inline T CHMAX(T& a, const T b) { return a = (a < b) ? b : a; }
template<typename T> inline T CHMIN(T& a, const T b) { return a = (a > b) ? b : a; }
#define EXCEPTION(msg) throw std::string("Exception : " msg " [ in ") + __func__ + " : " + std::to_string(__LINE__) + " lines ]"
#define TRY(cond, msg) try {if (cond) EXCEPTION(msg);}catch (std::string s) {std::cerr << s << std::endl;}
void CHECKTIME(std::function<void()> f) { auto start = std::chrono::system_clock::now(); f(); auto end = std::chrono::system_clock::now(); auto res = std::chrono::duration_cast<std::chrono::nanoseconds>((end - start)).count(); std::cerr << "[Time:" << res << "ns  (" << res / (1.0e9) << "s)]\n"; }

// test
template<class T> std::vector<std::vector<T>> VV(int n, int m, T init = T()) {
	return std::vector<std::vector<T>>(n, std::vector<T>(m, init));
}
template<typename S, typename T>
std::ostream& operator<<(std::ostream& os, std::pair<S, T> p) {
	os << "(" << p.first << ", " << p.second << ")"; return os;
}

// type/const
#define int ll
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using PAIR = std::pair<int, int>;
using PAIRLL = std::pair<ll, ll>;
constexpr int INFINT = 1 << 30;                          // 1.07x10^ 9
constexpr int INFINT_LIM = (1LL << 31) - 1;              // 2.15x10^ 9
constexpr ll INFLL = 1LL << 60;                          // 1.15x10^18
constexpr ll INFLL_LIM = (1LL << 62) - 1 + (1LL << 62);  // 9.22x10^18
constexpr double EPS = 1e-9;
constexpr int MOD = 1000000007;
constexpr double PI = 3.141592653589793238462643383279;

template<class T, size_t N> void FILL(T(&a)[N], const T& val) { for (auto& x : a) x = val; }
template<class ARY, size_t N, size_t M, class T> void FILL(ARY(&a)[N][M], const T& val) { for (auto& b : a) FILL(b, val); }
template<class T> void FILL(std::vector<T>& a, const T& val) { for (auto& x : a) x = val; }
template<class ARY, class T> void FILL(std::vector<std::vector<ARY>>& a, const T& val) { for (auto& b : a) FILL(b, val); }

// ------------>8------------------------------------->8------------

std::map<int, std::string> map;
void update(int x, std::string s) {
	auto it = map.find(x);
	if (it == map.end() || it->second.size() > s.size()) {
		map[x] = s;
	}
}

signed main() {
	INIT;

	VAR(int, n);

	std::vector<std::string> ts(100000);
	REP(i, ts.size()) ts[i] = std::to_string(i);

	update(1, "1");
	FOR(i, 2, 100000) {
		std::string s = ts[i];
		update(i, s);
		s += '^';

		int j = 2;
		int now = i * i;
		while (now <= n) {
			update(now, s + ts[j]);
			now *= i;
			++j;
		}
	}
	FOR(i, 2, 100) FOR(j, i, 100) update(i * j, ts[i] + '*' + ts[j]);

	std::string anss(std::to_string(n));
	int ans = anss.size();

	auto ansupd = [&](std::string s) {
		if (ans > s.size()) {
			anss = s;
			ans = s.size();
		}
	};

	{
		if (map.count(n)) ansupd(map[n]);
	}

	for (int i = 2; i * i <= n; ++i) {
		int t = n / i;
		int r = n - i * t;
		std::string s;
		s += map.count(i) ? map[i] : std::to_string(i);
		s += "*";
		s += map.count(t) ? map[t] : std::to_string(t);
		if (r) {
			s += "+";
			s += map.count(r) ? map[r] : std::to_string(r);
		}
		ansupd(s);
	}

	for (auto& p : map) {
		auto calc = [&](int x, std::string s) {
			auto it = std::prev(map.upper_bound(n - x));
			if (it == map.end()) return;
			if (s.size() + 1 + it->second.size() >= ans) return;

			std::string ss(s + "+" + it->second);
			if (x + it->first == n) {
				ansupd(ss);
			}
			else {
				if (ss.size() + 2 >= ans) return;
				int r = n - x - it->first;
				ss += "+";
				ss += map.count(r) ? map[r] : std::to_string(r);
				ansupd(ss);
			}
		};

		calc(p.first, p.second);
		FOR(i, 2, 100) {
			if (p.first * i > n) break;
			calc(p.first * i, ts[i] + "*" + p.second);
		}
	}

	OUT(anss)BR;

	return 0;
}


// God be praised
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
unordered_map<ll, string> m;

int lenll (ll x) {
	int c = 1;
	while (x >= 10) {
		c++;
		x /= 10;
	}
	return c;
}

string getstr(ll x) {
	if (m.find(x) != m.end() && m[x].size() < lenll(x)) {
		return m[x];
	}
	return to_string(x);
}

int main() {
	// freopen("in.txt", "r", stdin);

	ll n;
	scanf("%lld", &n);

	ll sq = 100000;
	for (int i = 2, to = min(sq, n); i <= to; i++) {
		ll x = i;

		for (int j = 2; ; j++) {
			x *= i;
			if (x > n) break;

			string s = to_string(i) + "^" + to_string(j);
			if (m.find(x) == m.end() || m[x].size() > s.size()) {
				m[x] = s;
			}
		}
	}

	string ans = getstr(n);

	for (auto it : m) {
		ll x = it.first;
		ll y = n / x;
		ll a = n % x;

		string s = getstr(x);
		if (y > 1) s += "*" + getstr(y);
		if (a > 0) s += "+" + getstr(a);

		if (s.size() < ans.size()) {
			ans = s;
		}
	}

	printf("%s\n", ans.c_str());
	return 0;
}


// God be praised
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
unordered_map<ll, string> m;

int lenll (ll x) {
	int c = 1;
	while (x >= 10) {
		c++;
		x /= 10;
	}
	return c;
}

string getstr(ll x) {
	if (m.find(x) != m.end() && m[x].size() < lenll(x)) {
		return m[x];
	}
	return to_string(x);
}

int main() {
	freopen("in.txt", "r", stdin);

	ll n;
	scanf("%lld", &n);

	ll sq = 100000;
	for (int i = 2, to = min(sq, n); i <= to; i++) {
		ll x = i;

		for (int j = 2; ; j++) {
			x *= i;
			if (x > n) break;

			string s = to_string(i) + "^" + to_string(j);
			if (m.find(x) == m.end() || m[x].size() > s.size()) {
				m[x] = s;
			}
		}
	}

	string ans = getstr(n);

	for (auto it : m) {
		ll x = it.first;
		ll y = n / x;
		ll a = n % x;

		string s = getstr(x);
		if (y > 1) s += "*" + getstr(y);
		if (a > 0) s += "+" + getstr(a);

		if (s.size() < ans.size()) {
			ans = s;
		}
	}

	printf("%s\n", ans.c_str());
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const long long MX = 1e10 + 2;
long long n;
map<long long, string> m;

inline long long power(long long a, long long p) {
	long long res = 1, x = a;
	while (p) {
		if (p & 1)
			res = (res * x);
		x = (x * x);
		p >>= 1;
	}
	return res;
}

string solve(long long rem) {
	string tmp = to_string(rem);
	if (m.find(rem) != m.end() && m[rem].size() < tmp.size()) {
		tmp = m[rem];
	}
	return tmp;
}

int main() {
	scanf("%lld", &n);
	for (int i = 2; i <= 1e5 + 2; ++i) {
		for (int p = 2;; ++p) {
			long long cur = power(i, p);
			if (cur > MX)
				break;
			string tmp = to_string(i) + '^' + to_string(p);
			if (m.find(cur) == m.end() || m[cur].size() > tmp.size()) {
				m[cur] = tmp;
			}
		}
	}

	string ans = solve(n);
	for (pair<long long, string> p : m) {
		long long cur = p.first;
		if (cur > n)
			break;
		long long fac = n / cur;
		string f = solve(fac), tmp;
		if (f == "1")
			tmp = p.second;
		else
			tmp = solve(fac) + '*' + p.second;
		if (n % cur != 0) {
			long long rem = n % cur;
			tmp += '+' + solve(rem);
		}

		if (tmp.size() < ans.size()) {
			ans = tmp;
		}
	}

	printf("%s\n", ans.c_str());

	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 1e5 + 10;
int len[N];
void init()
{
	len[0] = 0;
	for (int i = 1; i < N; i++) len[i] = len[i / 10] + 1;
}
string combine(int x, int p1, int y, int p2, char c)
{
	return to_string(x) + "^" + to_string(p1) + c
		+ to_string(y) + "^" + to_string(p2);
}
string combine(int a, int b, int c, int d)
{
	string ret;
	if (a != 1) ret = to_string(a) + "*";
	ret += to_string(b) + "^" + to_string(c);
	if (d != 0) ret += "+" + to_string(d);
	return ret;
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	init();
	LL n;
	cin >> n;
	string str = to_string(n);
	int l = str.length();
	if (n == 10000000000LL)
	{
		cout << "10^10" << endl;
		return 0;
	}
	if (l < 4)
	{
		cout << n << endl;
		return 0;
	}
	int minv = l;
	map<LL, pair<int, int>> mc;
	for (int i = 2; 1LL * i*i <= n; i++)
	{
		LL cur = 1LL*i * i;
		int cnt = 1;
		while (cur <= n)
		{
			cnt++;
			if (len[i] + 1 + len[cnt] >= l) break;
			if (cur >= 1000)
			{
				if (mc.count(cur))
				{
					int x, p;
					tie(x, p) = mc[cur];
					if (len[x] + 1 + len[p] > len[i] + 1 + len[cnt])
					{
						mc[cur] = { i,cnt };
					}
				}
				else mc[cur] = { i,cnt };
			}
			cur *= i;
		}
	}
	pair<int, string> ans = { l,str };
	for (auto &pp : mc)
	{
		LL x = pp.first;
		if (mc.count(n - x))
		{
			int y, p;
			tie(y, p) = mc[n - x];
			string s = combine(pp.second.first, pp.second.second, y, p, '+');
			ans = min(ans, { (int)s.length(),s });
		}
		if (n%x == 0 && mc.count(n / x))
		{
			int y, p;
			tie(y, p) = mc[n - x];
			string s = combine(pp.second.first, pp.second.second, y, p, '*');
			ans = min(ans, { (int)s.length(),s });
		}
		int y, p;
		tie(y, p) = pp.second;
		string s = combine(n / x, y, p, n%x);
		ans = min(ans, { (int)s.length(),s });
	}
	cout << ans.second << endl;
	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 1e5 + 10;
int len[N];
map<LL, pair<int, int>> mc;
void init()
{
	len[0] = 0;
	for (int i = 1; i < N; i++) len[i] = len[i / 10] + 1;
}
string combine(int x, int p1, int y, int p2, char c)
{
	return to_string(x) + "^" + to_string(p1) + c
		+ to_string(y) + "^" + to_string(p2);
}
string refrain(int x)
{
	string str = to_string(x);
	pair<int, string> ans = { int(str.length()),str };
	if (mc.count(x))
	{
		int y, p;
		tie(y, p) = mc[x];
		string s = to_string(y) + "^" + to_string(p);
		ans = min(ans, { int(s.length()), s });
	}
	return ans.second;
}
string combine(int a, int b, int c, int d)
{
	string ret;
	if (a != 1) ret = refrain(a) + "*";
	ret += to_string(b) + "^" + to_string(c);
	if (d != 0) ret += "+" + refrain(d);
	return ret;
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	init();
	LL n;
	cin >> n;
	string str = to_string(n);
	int l = str.length();
	if (n == 10000000000LL)
	{
		cout << "10^10" << endl;
		return 0;
	}
	if (l < 4)
	{
		cout << n << endl;
		return 0;
	}
	int minv = l;
	for (int i = 2; 1LL * i*i <= n; i++)
	{
		LL cur = 1LL * i * i;
		int cnt = 1;
		while (cur <= n)
		{
			cnt++;
			if (len[i] + 1 + len[cnt] >= l) break;
			if (cur >= 1000)
			{
				if (mc.count(cur))
				{
					int x, p;
					tie(x, p) = mc[cur];
					if (len[x] + 1 + len[p] > len[i] + 1 + len[cnt])
					{
						mc[cur] = { i,cnt };
					}
				}
				else mc[cur] = { i,cnt };
			}
			cur *= i;
		}
	}
	pair<int, string> ans = { l,str };
	for (auto &pp : mc)
	{
		LL x = pp.first;
		if (mc.count(n - x))
		{
			int y, p;
			tie(y, p) = mc[n - x];
			string s = combine(pp.second.first, pp.second.second, y, p, '+');
			ans = min(ans, { (int)s.length(),s });
		}
		if (n%x == 0 && mc.count(n / x))
		{
			int y, p;
			tie(y, p) = mc[n / x];
			string s = combine(pp.second.first, pp.second.second, y, p, '*');
			ans = min(ans, { (int)s.length(),s });
		}
		int y, p;
		tie(y, p) = pp.second;
		string s = combine(n / x, y, p, n%x);
		ans = min(ans, { (int)s.length(),s });
	}
	cout << ans.second << endl;
	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 1e5 + 10;
int len[N];
void init()
{
	len[0] = 0;
	for (int i = 1; i < N; i++) len[i] = len[i / 10] + 1;
}
string combine(int x, int p1, int y, int p2, char c)
{
	return to_string(x) + "^" + to_string(p1) + c
		+ to_string(y) + "^" + to_string(p2);
}
string combine(int a, int b, int c, int d)
{
	string ret;
	if (a != 1) ret = to_string(a) + "*";
	ret += to_string(b) + "^" + to_string(c);
	if (d != 0) ret += "+" + to_string(d);
	return ret;
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	init();
	LL n;
	cin >> n;
	string str = to_string(n);
	int l = str.length();
	if (n == 10000000000LL)
	{
		cout << "10^10" << endl;
		return 0;
	}
	if (l < 4)
	{
		cout << n << endl;
	}
	int minv = l;
	map<LL, pair<int, int>> mc;
	for (int i = 2; 1LL * i*i <= n; i++)
	{
		LL cur = 1LL*i * i;
		int cnt = 1;
		while (cur <= n)
		{
			cnt++;
			if (len[i] + 1 + len[cnt] >= l) break;
			if (cur >= 1000)
			{
				if (mc.count(cur))
				{
					int x, p;
					tie(x, p) = mc[cur];
					if (len[x] + 1 + len[p] > len[i] + 1 + len[cnt])
					{
						mc[cur] = { i,cnt };
					}
				}
				else mc[cur] = { i,cnt };
			}
			cur *= i;
		}
	}
	pair<int, string> ans = { l,str };
	for (auto &pp : mc)
	{
		LL x = pp.first;
		if (mc.count(n - x))
		{
			int y, p;
			tie(y, p) = mc[n - x];
			string s = combine(pp.second.first, pp.second.second, y, p, '+');
			ans = min(ans, { (int)s.length(),s });
		}
		if (n%x == 0 && mc.count(n / x))
		{
			int y, p;
			tie(y, p) = mc[n - x];
			string s = combine(pp.second.first, pp.second.second, y, p, '*');
			ans = min(ans, { (int)s.length(),s });
		}
		int y, p;
		tie(y, p) = pp.second;
		string s = combine(n / x, y, p, n%x);
		ans = min(ans, { (int)s.length(),s });
	}
	cout << ans.second << endl;
	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 1e5 + 10;
int len[N];
void init()
{
	len[0] = 0;
	for (int i = 1; i < N; i++) len[i] = len[i / 10] + 1;
}
string combine(int x, int p1, int y, int p2, char c)
{
	return to_string(x) + "^" + to_string(p1) + c
		+ to_string(y) + "^" + to_string(p2);
}
string combine(int a, int b, int c, int d)
{
	string ret;
	if (a != 1) ret = to_string(a) + "*";
	ret += to_string(b) + "^" + to_string(c);
	if (d != 0) ret += "+" + to_string(d);
	return ret;
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	init();
	LL n;
	cin >> n;
	string str = to_string(n);
	int l = str.length();
	if (n == 10000000000LL)
	{
		cout << "10^10" << endl;
		return 0;
	}
	if (l < 4)
	{
		cout << n << endl;
	}
	int minv = l;
	map<LL, pair<int, int>> mc;
	for (int i = 2; 1LL * i*i <= n; i++)
	{
		LL cur = 1LL*i * i;
		int cnt = 1;
		while (cur <= n)
		{
			cnt++;
			if (len[i] + 1 + len[cnt] >= l) break;
			if (cur >= 1000)
			{
				if (mc.count(cur))
				{
					int x, p;
					tie(x, p) = mc[cur];
					if (len[x] + 1 + len[p] > len[i] + 1 + len[cnt])
					{
						mc[cur] = { i,cnt };
					}
				}
				else mc[cur] = { i,cnt };
			}
			cur *= i;
		}
	}
	pair<int, string> ans = { l,str };
	for (auto &pp : mc)
	{
		LL x = pp.first;
		if (mc.count(n - x))
		{
			int y, p;
			tie(y, p) = mc[n - x];
			string s = combine(pp.second.first, pp.second.second, y, p, '+');
			ans = min(ans, { (int)s.length(),s });
		}
		if (n%x == 0 && mc.count(n / x))
		{
			int y, p;
			tie(y, p) = mc[n - x];
			string s = combine(pp.second.first, pp.second.second, y, p, '+');
			ans = min(ans, { (int)s.length(),s });
		}
		int y, p;
		tie(y, p) = pp.second;
		string s = combine(n / x, y, p, n%x);
		ans = min(ans, { (int)s.length(),s });
	}
	cout << ans.second << endl;
	return 0;
}


#include<bits/stdc++.h>
#define RAN(v)v.begin(),v.end()
#define pb push_back
#define lb lower_bound
#define ub upper_bound
using namespace std;
template<class T1,class T2>
inline void upd1(T1&a,T2 b){a>b?a=b:0;}
template<class T1,class T2>
inline void upd2(T1&a,T2 b){a<b?a=b:0;}
typedef long long ll;
struct ano{
	operator ll(){
		ll x=0,y=0,c=getchar();
		while(c<48)
			y=c==45,c=getchar();
		while(c>47)
			x=x*10+c-48,c=getchar();
		return y?-x:x;
	}
}buf;
inline int len(ll n){
	int s=0;
	for(;n;n/=10)
		++s;
	return s;
}
string str(ll n){
	ostringstream o;
	o<<n;
	return o.str();
}
string str(array<ll,5>a){
	ostringstream o;
	if(a[1]!=1){
		o<<a[1];
		if(a[2]!=1)
			o<<"^"<<a[2];
		o<<"*";
	}
	o<<a[3]<<"^"<<a[4];
	return o.str();
}
int main(){
	const ll inf=1e10-1;
	vector<array<ll,5>>f[10];
	int t[6][2]={0,0,2,9};
	for(int i=2;i<=5;++i){
		t[i][0]=t[i-1][1]+1;
		t[i][1]=t[i][0]*10-1;
	}
	auto sol1=[&](int k){
		if(k>5)
			return;
		for(int i=t[k][0];i<=t[k][1];++i){
			ll a=i;
			for(int j=2;;++j){
				if(a>inf/i)
					break;
				a*=i;
				int l=k+1+len(j);
				if(l<len(a))
					f[l].pb({a,1,1,i,j});
			}
		}
	};
	auto sol2=[&](int j,int k){
		for(auto s:f[j])
			for(int i=t[k][0];i<=t[k][1];++i){
				ll a=s[0];
				if(a>inf/i)
					break;
				a*=i;
				int l=k+1+j;
				if(l<len(a))
					f[l].pb({a,i,1,s[2],s[3]});
			}
	};
	auto sol3=[&](int j,int k){
		for(auto a:f[j])
			for(auto b:f[k])
				if(a[0]<=inf/b[0]){
					ll s=a[0]*b[0];
					int l=j+1+k;
					if(l<len(s))
						f[l].pb({s,a[3],a[4],b[3],b[4]});
				}
	};
	for(int i=2;i<=9;++i){
		ll a=i;
		for(int j=2;j<=9;++j){
			if(a>inf/i)
				break;
			a*=i;
			if(3<len(a))
				f[3].pb({a,1,1,i,j});
		}
	}
	for(int i=3;i<=9;++i){
		sol1(i-2);
		for(int j=3;j<=i-2;++j)
			for(int k=1;k+1+j<=i;++k)
				sol2(j,k);
		for(int j=3;j<=4;++j)
			for(int k=j;j+1+k<=i;++k)
				sol3(j,k);
		if(i<=6){
			sort(RAN(f[i]));
			int m=1;
			for(auto a:f[i])
				if(a[0]!=f[i][m-1][0])
					f[i][m++]=a;
			while(f[i].size()>m)
				f[i].pop_back();
		}
	}
	ll n=buf;
	if(n>inf)
		return!~puts("10^10");
	string ans=str(n);
	for(int i=3;i<len(n);++i)
		for(auto a:f[i]){
			ll m=a[0];
			if(n==m&&i<ans.size())
				ans=str(a);
			if(n>m&&i+1+len(n-m)<ans.size())
				ans=str(a)+"+"+str(n-m);
		}
	for(int i=3;i<=4;++i)
		for(auto a:f[i])
			for(int j=i;i+j<=8;++j)
				for(auto b:f[j]){
					ll m=a[0]+b[0];
					if(n==m&&i+1+j<ans.size())
						ans=str(a)+"+"+str(b);
					if(n>m&&i+j+len(n-m)+2<ans.size())
						ans=str(a)+"+"+str(b)+"+"+str(n-m);
				}
	cout<<ans<<endl;
}


#include<bits/stdc++.h>
#define RAN(v)v.begin(),v.end()
#define pb push_back
#define lb lower_bound
#define ub upper_bound
using namespace std;
template<class T1,class T2>
inline void upd1(T1&a,T2 b){a>b?a=b:0;}
template<class T1,class T2>
inline void upd2(T1&a,T2 b){a<b?a=b:0;}
typedef long long ll;
struct ano{
	operator ll(){
		ll x=0,y=0,c=getchar();
		while(c<48)
			y=c==45,c=getchar();
		while(c>47)
			x=x*10+c-48,c=getchar();
		return y?-x:x;
	}
}buf;
inline int len(ll n){
	int s=0;
	for(;n;n/=10)
		++s;
	return s;
}
string str(ll n){
	ostringstream o;
	o<<n;
	return o.str();
}
string str(array<ll,4>a){
	ostringstream o;
	if(a[1]!=1)
		o<<a[1]<<"*";
	o<<a[2]<<"^"<<a[3];
	return o.str();
}
int main(){
	const ll inf=1e10-1;
	vector<array<ll,4>>f[10];
	int t[6][2]={0,0,2,9};
	for(int i=2;i<=5;++i){
		t[i][0]=t[i-1][1]+1;
		t[i][1]=t[i][0]*10-1;
	}
	auto sol1=[&](int k){
		if(k>5)
			return;
		for(int i=t[k][0];i<=t[k][1];++i){
			ll a=i;
			for(int j=2;;++j){
				if(a>inf/i)
					break;
				a*=i;
				int l=k+1+len(j);
				if(l<len(a))
					f[l].pb({a,1,i,j});
			}
		}
	};
	auto sol2=[&](int j,int k){
		for(auto s:f[j])
			for(int i=t[k][0];i<=t[k][1];++i){
				ll a=s[0];
				if(a>inf/i)
					break;
				a*=i;
				int l=k+1+j;
				if(l<len(a))
					f[l].pb({a,i,s[2],s[3]});
			}
	};
	for(int i=2;i<=9;++i){
		ll a=i;
		for(int j=2;j<=9;++j){
			if(a>inf/i)
				break;
			a*=i;
			int l=2+len(j);
			if(l<len(a))
				f[l].pb({a,1,i,j});
		}
	}
	for(int i=3;i<=9;++i){
		sol1(i-2);
		for(int j=1;j<=i-4;++j)
			sol2(i-j-1,j);
	}
	ll n=buf;
	if(n>inf)
		return!~puts("10^10");
	string ans=str(n);
	for(int i=3;i<len(n);++i)
		for(auto a:f[i]){
			ll m=a[0];
			if(n==m&&i<ans.size())
				ans=str(a);
			if(n>m&&i+1+len(n-m)<ans.size())
				ans=str(a)+"+"+str(n-m);
		}
	for(int i=3;i<=4;++i)
		for(auto a:f[i])
			for(int j=i;i+j<=8;++j)
				for(auto b:f[j]){
					ll m=a[0]+b[0];
					if(n==m&&i+1+j<ans.size())
						ans=str(a)+"+"+str(b);
					if(n>m&&i+j+len(n-m)+2<ans.size())
						ans=str(a)+"+"+str(b)+"+"+str(n-m);
				}
	cout<<ans<<endl;
}


#include<bits/stdc++.h>
#define RAN(v)v.begin(),v.end()
#define pb push_back
#define lb lower_bound
#define ub upper_bound
using namespace std;
template<class T1,class T2>
inline void upd1(T1&a,T2 b){a>b?a=b:0;}
template<class T1,class T2>
inline void upd2(T1&a,T2 b){a<b?a=b:0;}
typedef long long ll;
struct ano{
	operator ll(){
		ll x=0,y=0,c=getchar();
		while(c<48)
			y=c==45,c=getchar();
		while(c>47)
			x=x*10+c-48,c=getchar();
		return y?-x:x;
	}
}buf;
inline int len(ll n){
	int s=0;
	for(;n;n/=10)
		++s;
	return s;
}
string str(ll n){
	ostringstream o;
	o<<n;
	return o.str();
}
string str(array<ll,4>a){
	ostringstream o;
	if(a[1]!=1)
		o<<a[1]<<"*";
	o<<a[2]<<"^"<<a[3];
	return o.str();
}
int main(){
	const ll inf=1e10-1;
	vector<array<ll,4>>f[10];
	int t[6][2]={0,0,2,9};
	for(int i=2;i<=5;++i){
		t[i][0]=t[i-1][1]+1;
		t[i][1]=t[i][0]*10-1;
	}
	auto sol1=[&](int k){
		if(k>5)
			return;
		for(int i=t[k][0];i<=t[k][1];++i){
			ll a=i;
			for(int j=2;;++j){
				if(a>inf/i)
					break;
				a*=i;
				int l=k+1+len(j);
				if(l<len(a))
					f[l].pb({a,1,i,j});
			}
		}
	};
	auto sol2=[&](int j,int k){
		for(auto s:f[j])
			for(int i=t[k][0];i<=t[k][1];++i){
				ll a=s[0];
				if(a>inf/i)
					break;
				a*=i;
				int l=k+1+j;
				if(l<len(a))
					f[l].pb({a,i,s[2],s[3]});
			}
	};
	for(int i=2;i<=9;++i){
		ll a=i;
		for(int j=2;j<=9;++j){
			if(a>inf/i)
				break;
			a*=i;
			int l=2+len(j);
			if(l<len(a))
				f[l].pb({a,1,i,j});
		}
	}
	for(int i=3;i<=9;++i){
		sol1(i-2);
		for(int j=1;j<=i-4;++j)
			sol2(i-j-1,j);
	}
	ll n=buf;
	if(n>inf)
		return!~puts("10^10");
	string ans=str(n);
	for(int i=3;i<len(n);++i)
		for(auto a:f[i]){
			ll m=a[0];
			if(n==m&&i<ans.size())
				ans=str(a);
			if(n>m&&i+1+len(n-m)<ans.size())
				ans=str(a)+"+"+str(n-m);
		}
	for(int i=3;i<=4;++i)
		for(auto a:f[i])
			for(int j=i;j<=4;++j)
				for(auto b:f[j]){
					ll m=a[0]+b[0];
					if(n==m&&i+1+j<ans.size())
						ans=str(a)+"+"+str(b);
					if(n>m&&i+j+len(n-m)+2<ans.size())
						ans=str(a)+"+"+str(b)+"+"+str(n-m);
				}
	cout<<ans<<endl;
}


#include<bits/stdc++.h>
#define RAN(v)v.begin(),v.end()
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define a first
#define b second
using namespace std;
template<class T1,class T2>
inline void upd1(T1&a,T2 b){a>b?a=b:0;}
template<class T1,class T2>
inline void upd2(T1&a,T2 b){a<b?a=b:0;}
typedef long long ll;
struct ano{
	operator ll(){
		ll x=0,y=0,c=getchar();
		while(c<48)
			y=c==45,c=getchar();
		while(c>47)
			x=x*10+c-48,c=getchar();
		return y?-x:x;
	}
}buf;
inline int len(ll n){
	int s=0;
	for(;n;n/=10)
		++s;
	return s;
}
string str(ll n){
	ostringstream o;
	o<<n;
	return o.str();
}
string str(array<int,4>a){
	ostringstream o;
	if(a[0]!=1){
		o<<a[0];
		if(a[1]!=1)
			o<<"^"<<a[1];
		o<<"*";
	}
	o<<a[2]<<"^"<<a[3];
	return o.str();
}
int cal(ll n){
	return n?len(n)+1:0;
}
int main(){
	const ll inf=1e10-1;
	vector<pair<ll,array<int,4>>>f[10];
	array<int,2>t[6];
	t[1]={2,9};
	for(int i=2;i<=5;++i){
		t[i][0]=t[i-1][1]+1;
		t[i][1]=t[i][0]*10-1;
	}
	auto sol1=[&](int k){
		if(k>5)
			return;
		for(int i=t[k][0];i<=t[k][1];++i){
			ll a=i;
			for(int j=2;;++j){
				if(a>inf/i)
					break;
				a*=i;
				int l=k+1+len(j);
				if(l<len(a))
					f[l].pb({a,{1,1,i,j}});
			}
		}
	};
	auto sol2=[&](int j,int k){
		for(auto s:f[j])
			for(int i=t[k][0];i<=t[k][1];++i){
				ll a=s.a;
				if(a>inf/i)
					break;
				a*=i;
				int l=k+1+j;
				if(l<len(a))
					f[l].pb({a,{i,1,s.b[2],s.b[3]}});
			}
	};
	auto sol3=[&](int j,int k){
		for(auto a:f[j])
			for(auto b:f[k])
				if(a.a<=inf/b.a){
					ll s=a.a*b.a;
					int l=j+1+k;
					if(l<len(s))
						f[l].pb({s,{a.b[2],a.b[3],b.b[2],b.b[3]}});
				}
	};
	for(int i=2;i<=9;++i){
		ll a=i;
		for(int j=2;j<=9;++j){
			if(a>inf/i)
				break;
			a*=i;
			if(3<len(a))
				f[3].pb({a,{1,1,i,j}});
		}
	}
	for(int i=3;i<=9;++i){
		sol1(i-2);
		for(int j=3;j<=i-2;++j)
			for(int k=1;k+1+j<=i;++k)
				sol2(j,k);
		for(int j=3;j<=4;++j)
			for(int k=j;j+1+k<=i;++k)
				sol3(j,k);
		if(i<=6){
			sort(RAN(f[i]));
			int m=1;
			for(auto a:f[i])
				if(a.a!=f[i][m-1].a)
					f[i][m++]=a;
			f[i].resize(m);
		}
	}
	ll n=buf;
	if(n>inf)
		return!~puts("10^10");
	string ans=str(n);
	for(int i=3;i<len(n);++i)
		for(auto a:f[i]){
			ll m=a.a;
			if(n>=m){
				ll s=cal(n-m);
				if(i+s<ans.size()){
					ans=str(a.b);
					if(s)
						ans+="+"+str(n-m);
				}
			}
		}
	for(int i=3;i<=4;++i)
		for(auto a:f[i])
			for(int j=i;i+j<=8;++j)
				for(auto b:f[j]){
					ll m=a.a+b.a;
					if(n>=m){
						ll s=cal(n-m);
						if(i+1+j+s<ans.size()){
							ans=str(a.b)+"+"+str(b.b);
							if(s)
								ans+="+"+str(n-m);
						}
					}
				}
	cout<<ans<<endl;
}


#include<bits/stdc++.h>
#define RAN(v)v.begin(),v.end()
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define a first
#define b second
using namespace std;
template<class T1,class T2>
inline void upd1(T1&a,T2 b){a>b?a=b:0;}
template<class T1,class T2>
inline void upd2(T1&a,T2 b){a<b?a=b:0;}
typedef long long ll;
struct ano{
	operator ll(){
		ll x=0,y=0,c=getchar();
		while(c<48)
			y=c==45,c=getchar();
		while(c>47)
			x=x*10+c-48,c=getchar();
		return y?-x:x;
	}
}buf;
inline int len(ll n){
	int s=0;
	for(;n;n/=10)
		++s;
	return s;
}
string str(ll n){
	ostringstream o;
	o<<n;
	return o.str();
}
string str(array<int,4>a){
	ostringstream o;
	if(a[0]!=1){
		o<<a[0];
		if(a[1]!=1)
			o<<"^"<<a[1];
		o<<"*";
	}
	o<<a[2]<<"^"<<a[3];
	return o.str();
}
int cal(ll n){
	return n?len(n)+1:0;
}
int main(){
	const ll inf=1e10-1;
	vector<pair<ll,array<int,4>>>f[10];
	array<int,2>t[6];
	t[1]={2,9};
	for(int i=2;i<=5;++i){
		t[i][0]=t[i-1][1]+1;
		t[i][1]=t[i][0]*10-1;
	}
	auto sol1=[&](int k){
		if(k>5)
			return;
		for(int i=t[k][0];i<=t[k][1];++i){
			ll a=i;
			for(int j=2;;++j){
				if(a>inf/i)
					break;
				a*=i;
				int l=k+1+len(j);
				if(l<len(a))
					f[l].pb({a,{1,1,i,j}});
			}
		}
	};
	auto sol2=[&](int j,int k){
		for(auto s:f[j])
			for(int i=t[k][0];i<=t[k][1];++i){
				ll a=s.a;
				if(a>inf/i)
					break;
				a*=i;
				int l=k+1+j;
				if(l<len(a))
					f[l].pb({a,{i,1,s.b[2],s.b[3]}});
			}
	};
	auto sol3=[&](int j,int k){
		for(auto a:f[j])
			for(auto b:f[k])
				if(a.a<=inf/b.a){
					ll s=a.a*b.a;
					int l=j+1+k;
					if(l<len(s))
						f[l].pb({s,{a.b[3],a.b[4],b.b[3],b.b[4]}});
				}
	};
	for(int i=2;i<=9;++i){
		ll a=i;
		for(int j=2;j<=9;++j){
			if(a>inf/i)
				break;
			a*=i;
			if(3<len(a))
				f[3].pb({a,{1,1,i,j}});
		}
	}
	for(int i=3;i<=9;++i){
		sol1(i-2);
		for(int j=3;j<=i-2;++j)
			for(int k=1;k+1+j<=i;++k)
				sol2(j,k);
		for(int j=3;j<=4;++j)
			for(int k=j;j+1+k<=i;++k)
				sol3(j,k);
		if(i<=6){
			sort(RAN(f[i]));
			int m=1;
			for(auto a:f[i])
				if(a.a!=f[i][m-1].a)
					f[i][m++]=a;
			while(f[i].size()>m)
				f[i].pop_back();
		}
	}
	ll n=buf;
	if(n>inf)
		return!~puts("10^10");
	string ans=str(n);
	for(int i=3;i<len(n);++i)
		for(auto a:f[i]){
			ll m=a.a;
			if(n>=m){
				ll s=cal(n-m);
				if(i+s<ans.size()){
					ans=str(a.b);
					if(s)
						ans+="+"+str(n-m);
				}
			}
		}
	for(int i=3;i<=4;++i)
		for(auto a:f[i])
			for(int j=i;i+j<=8;++j)
				for(auto b:f[j]){
					ll m=a.a+b.a;
					if(n>=m){
						ll s=cal(n-m);
						if(i+1+j+s<ans.size()){
							ans=str(a.b)+"+"+str(b.b);
							if(s)
								ans+="+"+str(n-m);
						}
					}
				}
	cout<<ans<<endl;
}


#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <ctime>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
#define enable_ll
#ifdef enable_ll
    #define int long long
#endif
#ifdef DEBUG
    #define out(u) cout<<u<<" "
    #define outln(u) cout<<u<<endl
    #define see(u) cout<<#u<<"="<<u<<" "
    #define seeln(u) cout<<#u<<"="<<u<<endl
    #define line cout<<"---------------------\n"
#else
    #define out(u)
    #define outln(u)
    #define see(u)
    #define seeln(u)
    #define line
#endif
#define m_p make_pair
#define pii pair<int,int>
#define piii pair<int,pii>
#define piiii pair<pii,pii>
#define sz(x) x.size()
#define fastio ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
template <class T> void read(T &u)
{
    u=0; char c=getchar(); int flag=0;
    while (c<'0'||c>'9') flag|=(c=='-'),c=getchar();
    while (c>='0'&&c<='9') u=(u<<3)+(u<<1)+(c^48),c=getchar();
    if (flag) u=-u;
}
template <class T> bool checkmin(T &a,T b){return (b<a ? a=b,1 : 0);}
template <class T> bool checkmax(T &a,T b){return (b>a ? a=b,1 : 0);}
template <class T> T _min(T a,T b){return (a<b ? a : b);}
template <class T> T _max(T a,T b){return (a>b ? a : b);}
const int lim=10000000000;
int n;
string ans="";
string get_str(int x)
{
    string t="";
    while (x)
    {
        t+=('0'+x%10);
        x/=10;
    }
    reverse(t.begin(),t.end());
    return t;
}

int num(int x)
{
    int tmp=0;
    while (x)
    {
        ++tmp;
        x/=10;
    }
    return tmp;
}

int qpow(int a,int b)
{
    int ans=1;
    while (b)
    {
        if (b&1) ans=ans*a;
        a=a*a;
        b>>=1;
    }
    return ans;
}

vector <piiii> v,w;
void init()
{
    cin>>n;
    ans=get_str(n);
    for (int i=2;i<=33;++i)
    {
        int R=(int)pow(lim+lim,1.0/i);
        for (int j=2;j<=R;++j)
        {
            int p=num(j)+1+num(i);
            int x=qpow(j,i);
            if (x>lim) break;
            v.push_back(m_p(m_p(x,p),m_p(j,i)));
        }
    }
    sort(v.begin(),v.end());
    for (int i=0;i<(int)v.size();++i)
    {
        if (i!=0&&v[i].first.first==v[i-1].first.first)
        {
            continue;
        }
        w.push_back(v[i]);
    }
    for (int i=0;i<(int)w.size();++i)
    {
        //cout<<w[i].first.first<<" "<<w[i].first.second<<" "<<w[i].second.first<<" "<<w[i].second.second<<endl;
        if (w[i].first.first==n)
        {
            if (w[i].first.second<sz(ans))
            {
                ans=get_str(w[i].second.first)+"^"+get_str(w[i].second.second);
            }
        }
        if (w[i].first.first<n)
        {
            int x=n-w[i].first.first;
            if (w[i].first.second+1+num(x)<sz(ans))
            {
                ans=get_str(w[i].second.first)+"^"+get_str(w[i].second.second)+"+"+get_str(x);
            }
            piiii tmp=*lower_bound(w.begin(),w.end(),m_p(m_p(x,0LL),m_p(0LL,0LL)));
            if (tmp.first.first==x)
            {
                if (w[i].first.second+1+tmp.first.second<sz(ans))
                {
                     ans=get_str(w[i].second.first)+"^"+get_str(w[i].second.second)+"+"+get_str(tmp.second.first)+"^"+get_str(tmp.second.second);
                }
            }
        }
        if (n%w[i].first.first==0)
        {
            int x=n/w[i].first.first;
            if (w[i].first.second+1+num(x)<sz(ans))
            {
                ans=get_str(w[i].second.first)+"^"+get_str(w[i].second.second)+"*"+get_str(x);
            }
            piiii tmp=*lower_bound(w.begin(),w.end(),m_p(m_p(x,0LL),m_p(0LL,0LL)));
            if (tmp.first.first==x)
            {
                if (w[i].first.second+1+tmp.first.second<sz(ans))
                {
                     ans=get_str(w[i].second.first)+"^"+get_str(w[i].second.second)+"*"+get_str(tmp.second.first)+"^"+get_str(tmp.second.second);
                }
            }
        }
        if (w[i].first.first<n)
        {
            int big=n/w[i].first.first,now=9;
            int res=n%w[i].first.first;
            if (w[i].first.second+1+num(big)+1+num(res)<sz(ans))
            {
                ans=get_str(w[i].second.first)+"^"+get_str(w[i].second.second)+"*"+get_str(big)+"+"+get_str(res);
            }
            while (now<=big)
            {
                res=n-now*w[i].first.first;
                if (w[i].first.second+1+num(now)+1+num(res)<sz(ans))
                {
                    ans=get_str(w[i].second.first)+"^"+get_str(w[i].second.second)+"*"+get_str(now)+"+"+get_str(res);
                }
                now=now*10+9;
            }
        }
    }
}

int P[13][13];
void solve()
{
    if (sz(ans)<=9)
    {
        cout<<ans<<endl;
        return;
    }
    for (int a=0;a<=9;++a)
    {
        for (int b=0;b<=9;++b)
        {
            P[a][b]=qpow(a,b);
        }
    }
    for (int a=0;a<=9;++a)
    {
        for (int b=0;b<=9;++b)
        {
            for (int c=0;c<=9;++c)
            {
                for (int d=0;d<=9;++d)
                {
                    for (int e=0;e<=9;++e)
                    {
                        if (P[a][b]+P[c][d]+e==n)
                        {
                            cout<<get_str(a)<<"^"<<get_str(b)<<"+"<<get_str(c)<<"^"<<get_str(d)<<"+"<<get_str(e)<<endl;
                            return;
                        }
                        if (P[a][b]*c+P[d][e]==n)
                        {
                            cout<<get_str(a)<<"^"<<get_str(b)<<"*"<<get_str(c)<<"+"<<get_str(d)<<"^"<<get_str(e)<<endl;
                            return;
                        }
                        if (P[a][b]*P[c][d]*e==n)
                        {
                            cout<<get_str(a)<<"^"<<get_str(b)<<"*"<<get_str(c)<<"^"<<get_str(d)<<"*"<<get_str(e)<<endl;
                            return;
                        }
                        if (P[a][b]*P[c][d]+e==n)
                        {
                            cout<<get_str(a)<<"^"<<get_str(b)<<"*"<<get_str(c)<<"^"<<get_str(d)<<"+"<<get_str(e)<<endl;
                            return;
                        }
                    }
                }
            }
        }
    }
    cout<<ans<<endl;
}

#undef int
int main()
{
    init();
    solve();
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <ctime>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
#define enable_ll
#ifdef enable_ll
    #define int long long
#endif
#ifdef DEBUG
    #define out(u) cout<<u<<" "
    #define outln(u) cout<<u<<endl
    #define see(u) cout<<#u<<"="<<u<<" "
    #define seeln(u) cout<<#u<<"="<<u<<endl
    #define line cout<<"---------------------\n"
#else
    #define out(u)
    #define outln(u)
    #define see(u)
    #define seeln(u)
    #define line
#endif
#define m_p make_pair
#define pii pair<int,int>
#define piii pair<int,pii>
#define piiii pair<pii,pii>
#define sz(x) x.size()
#define fastio ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
template <class T> void read(T &u)
{
    u=0; char c=getchar(); int flag=0;
    while (c<'0'||c>'9') flag|=(c=='-'),c=getchar();
    while (c>='0'&&c<='9') u=(u<<3)+(u<<1)+(c^48),c=getchar();
    if (flag) u=-u;
}
template <class T> bool checkmin(T &a,T b){return (b<a ? a=b,1 : 0);}
template <class T> bool checkmax(T &a,T b){return (b>a ? a=b,1 : 0);}
template <class T> T _min(T a,T b){return (a<b ? a : b);}
template <class T> T _max(T a,T b){return (a>b ? a : b);}
const int lim=10000000000;
int n;
string ans="";
string get_str(int x)
{
    string t="";
    while (x)
    {
        t+=('0'+x%10);
        x/=10;
    }
    reverse(t.begin(),t.end());
    return t;
}

int num(int x)
{
    int tmp=0;
    while (x)
    {
        ++tmp;
        x/=10;
    }
    return tmp;
}

int qpow(int a,int b)
{
    int ans=1;
    while (b)
    {
        if (b&1) ans=ans*a;
        a=a*a;
        b>>=1;
    }
    return ans;
}

vector <piiii> v,w;
void init()
{
    cin>>n;
    ans=get_str(n);
    for (int i=2;i<=33;++i)
    {
        int R=(int)pow(lim+lim,1.0/i);
        for (int j=2;j<=R;++j)
        {
            int p=num(j)+1+num(i);
            int x=qpow(j,i);
            if (x>lim) break;
            v.push_back(m_p(m_p(x,p),m_p(j,i)));
        }
    }
    sort(v.begin(),v.end());
    for (int i=0;i<(int)v.size();++i)
    {
        if (i!=0&&v[i].first.first==v[i-1].first.first)
        {
            continue;
        }
        w.push_back(v[i]);
    }
    for (int i=0;i<(int)w.size();++i)
    {
        //cout<<w[i].first.first<<" "<<w[i].first.second<<" "<<w[i].second.first<<" "<<w[i].second.second<<endl;
        if (w[i].first.first==n)
        {
            if (w[i].first.second<sz(ans))
            {
                ans=get_str(w[i].second.first)+"^"+get_str(w[i].second.second);
            }
        }
        if (w[i].first.first<n)
        {
            int x=n-w[i].first.first;
            if (w[i].first.second+1+num(x)<sz(ans))
            {
                ans=get_str(w[i].second.first)+"^"+get_str(w[i].second.second)+"+"+get_str(x);
            }
            piiii tmp=*lower_bound(w.begin(),w.end(),m_p(m_p(x,0LL),m_p(0LL,0LL)));
            if (tmp.first.first==x)
            {
                if (w[i].first.second+1+tmp.first.second<sz(ans))
                {
                     ans=get_str(w[i].second.first)+"^"+get_str(w[i].second.second)+"+"+get_str(tmp.second.first)+"^"+get_str(tmp.second.second);
                }
            }
        }
        if (n%w[i].first.first==0)
        {
            int x=n/w[i].first.first;
            if (w[i].first.second+1+num(x)<sz(ans))
            {
                ans=get_str(w[i].second.first)+"^"+get_str(w[i].second.second)+"*"+get_str(x);
            }
            piiii tmp=*lower_bound(w.begin(),w.end(),m_p(m_p(x,0LL),m_p(0LL,0LL)));
            if (tmp.first.first==x)
            {
                if (w[i].first.second+1+tmp.first.second<sz(ans))
                {
                     ans=get_str(w[i].second.first)+"^"+get_str(w[i].second.second)+"*"+get_str(tmp.second.first)+"^"+get_str(tmp.second.second);
                }
            }
        }
        if (w[i].first.first<n)
        {
            int big=n/w[i].first.first,now=9;
            int res=n%w[i].first.first;
            if (w[i].first.second+1+num(big)+1+num(res)<sz(ans))
            {
                ans=get_str(w[i].second.first)+"^"+get_str(w[i].second.second)+"*"+get_str(big)+"+"+get_str(res);
            }
            while (now<=big)
            {
                res=n-now*w[i].first.first;
                if (w[i].first.second+1+num(now)+1+num(res)<sz(ans))
                {
                    ans=get_str(w[i].second.first)+"^"+get_str(w[i].second.second)+"*"+get_str(now)+"+"+get_str(res);
                }
                now=now*10+9;
            }
        }
    }
}

vector <int> a;
vector <char> b;
int pri(char c)
{
    if (c=='+') return 1;
    else if (c=='*') return 2;
    else return 3;
}

int calc()
{
    vector <int> v;
    vector <char> w;
    for (int i=0;i<4;++i)
    {
        v.push_back(a[i]);
        while (!w.empty()&&pri(w.back())>pri(b[i]))
        {
            char ch=w.back(); w.pop_back();
            int y=v.back(); v.pop_back();
            int x=v.back(); v.pop_back();
            if (ch=='^') v.push_back(qpow(x,y));
            else if (ch=='*') v.push_back(x*y);
            else v.push_back(x+y);
        }
        w.push_back(b[i]);
    }
    v.push_back(a[4]);
    while (!w.empty())
    {
        char ch=w.back(); w.pop_back();
        int y=v.back(); v.pop_back();
        int x=v.back(); v.pop_back();
        if (ch=='^') v.push_back(qpow(x,y));
        else if (ch=='*') v.push_back(x*y);
        else v.push_back(x+y);
    }
    return v.back();
}

void dfs(int rnd)
{
    if (rnd>9)
    {
        string s="";
        for (int i=0;i<4;++i)
        {
            s+=(char)('0'+a[i]);
            s+=b[i];
        }
        s+=(char)('0'+a[4]);
        if (calc()==n)
        {
            ans=s;
        }
        return;
    }
    if (rnd<=5)
    {
        for (int i=0;i<=9;++i)
        {
            a.push_back(i);
            dfs(rnd+1);
            a.pop_back();
        }
    }
    else
    {
        if (rnd==6||b[rnd-5-1]!='^')
        {
            b.push_back('^');
            dfs(rnd+1);
            b.pop_back();
        }
        b.push_back('*');
        dfs(rnd+1);
        b.pop_back();
        b.push_back('+');
        dfs(rnd+1);
        b.pop_back();
    }
}

void solve()
{
    if (sz(ans)>9) dfs(1);
    cout<<ans<<endl;
}

#undef int
int main()
{
    init();
    solve();
    return 0;
}


#include <cstdio>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cctype>
#include <cassert>
#include <ciso646>
#include <climits>
#include <cmath>

#include <algorithm>
#include <utility>
#include <functional>
#include <numeric>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <set>
#include <deque>
#include <bitset>

using namespace std;
typedef long long ll;
typedef std::pair< int, int > pii;
typedef std::vector< int > vi;
typedef std::vector< pii > vii ;

#define fi first
#define se second
#define all(x)  (x).begin(), (x).end()
#define fore(i,a,b)  for(int i = (a), vzq_b = (b); i < vzq_b; ++i)
#define forn(i, n)  fore(i,0,n)

double const EPS = 1.0E-9 ;
int const MOD    = (int)1e9 + 7 ;
inline int read( char*   s ){  return scanf("%s", s) ; }
inline int read(int&x){  return scanf("%d", & ( x ) ); }
inline int read(ll&x){ return scanf("%lld",&x); }
inline int read(double &x){ return scanf("%lf", &x); }
inline int writeln(int x){ return printf("%d\n", x);}
inline int writeln(ll x ) { return printf("%lld\n", x ) ; }
inline int writeln(double x){ return printf("%.12f\n", x ) ; }
template< typename ...T> int read(T&...args){
    using swallow = int[];
    swallow w = { 0, ( read(args) ) ... } ;
    return sizeof( w ) / sizeof( w [ 0 ] ) - 1;
}

inline ll gcd(ll x,ll y) { return y == 0 ? x : gcd(y, x%y); }
inline ll lcm(ll x, ll y){ return x == 0 && y == 0  ? 0 : x/gcd(x,y) * y; }
inline ll powmod(ll x, ll n, ll m = MOD ) {
    ll r = 1;
    while(n){
        if (n&1) r = (r*x)%m;
        x = (x*x)%m;
        n/=2;
    }
    return r;
}

static int leap(int y){  return y % 4 == 0 && y% 100 != 0  || y % 400 == 0 ; }

static int const month[ 2 ][ 12 ] =
{
    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
    { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};

/********************************************************/
static const int maxn = 1 << 17 ;
static const int maxm = 1 << 20 ;

ll n ;
ll pw[ maxn ][ 15 ];

int ndigits(ll n ){
    int r = 0;
    do ++r; while(n/=10);
    return r;
}

string solve(ll n )
{
    int d = ndigits(n);
    std::string s = std::to_string(n);

    //1. n = a^b
    //2.  n = c * a ^ b

    //3.  n = a^b + c

    //4.  n = d*a^b + c, where c < 100, and d < 100

    //5. n = a * b
    //6  n = a * b + c
    //7. n = a + b

    for(int a = 1; a < maxn; ++a)
    {
        for(int b = 1; b < 15 && pw[a][b] <= n; ++b)
        {
            if (pw[a][b] == n )
            {
                size_t rn = ndigits(a) + 1 + ndigits(b);

                if (rn < s.length()) {
                    std::string r = std::to_string(a) + "^" + std::to_string(b);

                    s = r;
                }
            }

            if ( pw[a][b] > 1 && n % pw[a][b] == 0 )
            {
                ll c = n / pw[a][b];
                size_t rn = ndigits(c) + 2 + ndigits(a) + ndigits(b) ;
                if(rn < s.length() ) {
                    std::string r = std::to_string(c) + "*" + std::to_string(a) + "^" + std::to_string(b);

                        s = r;
                }
            }

            {
                ll c = n - pw[a][b];
                size_t rn = ndigits(c) + 2 + ndigits(a) + ndigits(b);
                if (rn < s.length() ) {
                    std::string r =  std::to_string(a) + "^" + std::to_string(b)+ "+" + std::to_string(c)   ;
                    s = r;
                }

            }
            // n - c = d * a ^ b
            {
                ll c = n % pw[a][b];
                ll d = n / pw[a][b];
                size_t rn = 3 + ndigits(d) + ndigits(a) + ndigits(b) + ndigits(c) ;
                if (rn < s.length() ) {
                    s = std::to_string(d) + "*" + to_string(a) + "^"+ to_string(b) + "+"+ to_string(c);
                }
            }
        }
    }

    for(int i = 1; i *1ll* i <= n; ++i)
    {

        ll a = i, b = n / i ;
        if (a * b == n ){
            size_t rn = ndigits(a) + 1 + ndigits(b);
            if (rn < s.length() ) {
                std::string r = to_string(a) + "*"+ to_string(b);
                s = r;
            }
        } else {
            ll c = n - a * b ;
            size_t rn = ndigits(a) + 2 + ndigits(b) + ndigits(c);
            if (rn < s.length()){
                std::string r = to_string(a) + "*" + to_string(b) + "+"+ to_string(c);
                s = r;
            }
        }

    }

    return s;

}
static void init()
{
    for(int i = 1; i < maxn ; ++i)
    {
        pw[i][0] = 1;
        for(int j = 1; j< 15; ++j){
            pw[i][j] = pw[i][j-1] * 1ll * i;
        }
    }
}

static int solve()
{
    init();
    read( n ) ;

    string s = solve(n);

    printf("%s\n", s.c_str());

    return 0 ;
}

int main(int argc, char * argv[] )
{

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif //end online-judge

    solve();
    return 0;
}


#include <cstdio>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cctype>
#include <cassert>
#include <ciso646>
#include <climits>
#include <cmath>

#include <algorithm>
#include <utility>
#include <functional>
#include <numeric>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <set>
#include <deque>
#include <bitset>

using namespace std;
typedef long long ll;
typedef std::pair< int, int > pii;
typedef std::vector< int > vi;
typedef std::vector< pii > vii ;

#define fi first
#define se second
#define all(x)  (x).begin(), (x).end()
#define fore(i,a,b)  for(int i = (a), vzq_b = (b); i < vzq_b; ++i)
#define forn(i, n)  fore(i,0,n)

double const EPS = 1.0E-9 ;
int const MOD    = (int)1e9 + 7 ;
inline int read( char*   s ){  return scanf("%s", s) ; }
inline int read(int&x){  return scanf("%d", & ( x ) ); }
inline int read(ll&x){ return scanf("%lld",&x); }
inline int read(double &x){ return scanf("%lf", &x); }
inline int writeln(int x){ return printf("%d\n", x);}
inline int writeln(ll x ) { return printf("%lld\n", x ) ; }
inline int writeln(double x){ return printf("%.12f\n", x ) ; }
template< typename ...T> int read(T&...args){
    using swallow = int[];
    swallow w = { 0, ( read(args) ) ... } ;
    return sizeof( w ) / sizeof( w [ 0 ] ) - 1;
}

inline ll gcd(ll x,ll y) { return y == 0 ? x : gcd(y, x%y); }
inline ll lcm(ll x, ll y){ return x == 0 && y == 0  ? 0 : x/gcd(x,y) * y; }
inline ll powmod(ll x, ll n, ll m = MOD ) {
    ll r = 1;
    while(n){
        if (n&1) r = (r*x)%m;
        x = (x*x)%m;
        n/=2;
    }
    return r;
}

static int leap(int y){  return y % 4 == 0 && y% 100 != 0  || y % 400 == 0 ; }

static int const month[ 2 ][ 12 ] =
{
    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
    { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};

/********************************************************/
static const int maxn = 1 << 19 ;
static const int maxm = 1 << 20 ;

std::map< ll, int > dp;
std::map< ll, std::string> rep;

int digits(ll n ){
    int r = 0;
    do r++; while(n/=10);
    return r;
}

int get_dp(ll n){
    auto it = dp.find(n);
    if (it != dp.end()) return (*it).second;

    return digits(n);
}

std::string get_rep(ll n )
{
    auto it = rep.find(n);
    if (it != rep.end()) return (*it).second;
    return ::std::to_string(n);
}

static int solve()
{
    ll n ;
    read(n);
    for(int a = 1; a <= 100000; ++a)
    {
        ll pw = a;
        for(int b = 2; b < 100; ++b)
        {
            pw *= a;
            if (pw > n ) break;

            // pw = a ^ b
            int pw_len = get_dp(pw);
            int cur_len = digits(a) + 1 + digits(b);
            if (cur_len < pw_len ) {
                dp[pw] = cur_len;
                rep[pw] = std::to_string(a) + "^" + std::to_string(b);
            }

            for(int mul = 2; mul < 55; ++mul)
            {
                // mul * a^b
                ll pw_m  = pw * mul ;
                if (pw_m > n) break;

                int pwm_len = get_dp(pw_m);
                int cur_pwm_len = cur_len + 1 + digits(mul);
                if (cur_pwm_len < pwm_len ) {
                    dp[pw_m] = cur_pwm_len;
                    rep[pw_m] = to_string(mul) + "*" + std::to_string(a) + "^" + std::to_string(b);
                }
            }
        }
    }

    std::string ans = get_rep(n);

    // mul * a^b + add
    // where mul and add also may be  c^d format.

    for(int a = 1; a <= 100000; ++a)
    {
        ll pw = a;
        for(int b = 2; b < 100; ++b)
        {
            pw *= a;
            if (pw > n ) break;

            ll mul = n / pw ;
            ll add = n % pw ;

            // mul * a^b + add
            int cur_len = get_dp(pw);
            if (mul > 1 ) cur_len += 1 + get_dp(mul);
            if (add > 0 ) cur_len += 1 + get_dp(add);

            if (cur_len < (int)ans.length() )
            {
                ans.clear();
                if (mul  > 1 ) ans += get_rep(mul) + "*";
                ans += get_rep(pw);
                if (add > 0 ) ans += "+" + get_rep(add);
            }
        }
    }

    printf("%s\n", ans.c_str());
    return 0 ;
}

int main(int argc, char * argv[] )
{

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif //end online-judge

    solve();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#include <string>
#include <sstream>
#include <set>

using namespace std ;

map <long long , string> dict ;
set <long long> record[10] ;

long long n ;
long long ten[11] ;

string toString(long long x){
    ostringstream os ;
    os << x ;
    return os.str() ;
}

int getlen(long long x){
    int t = 0 ;
    while(x){
        x /= 10 ;
        t += 1 ;
    }
    return (max(1 , t)) ;
}

void relax(long long x , string t){
    if(x > n || t.length() >= getlen(x)){
        return ;
    }
    if(dict.count(x) && dict[x].length() <= t.length()){
        return ;
    }
    //更新
    record[dict[x].length()].erase(x) ;
    dict[x] = t ;
    record[t.length()].insert(x) ;
}

string getString(long long x){
    if(dict.count(x)){
        return dict[x] ;
    }
    return toString(x) ;
}

void generatePowers(){
    for(long long x  = 2 ; x * x <= n; ++x){
        long long c = x * x ;
        int p = 2 ;
        while (c  <= n){
            string temp = toString(x) + "^" + toString(p) ;
            relax(c , temp) ;
            c *= x ;
            p += 1 ;
        }
    }
}

void generateMultiplyAndMultiply(int maxlen){
    for(int i = 1 ; i <= maxlen ; ++i){
        for(int j = i ; i + j + 1 <= maxlen ; ++j){
            for(auto x : record[i]){
                for (auto y : record[j]){
                    relax(x * y , getString(x) + "*" + getString(y)) ;
                }
            }
        }
    }
}

void generateMultiplayAndSimple(int maxlen){
    for(int i = 1 ; i <= maxlen ; ++i){
        for(long long x = 1 ; x < ten[maxlen - 1 - i] ; ++x){
            for (auto y : record[i]){
                relax(x * y , getString(y) + "*" + getString(x)) ;
            }
        }
    }
}

void prepare(){
    ten[0] = 1 ;
    for(int i = 1 ; i <= 10 ; ++i)
        ten[i] = 10 * ten[i - 1] ;
    generatePowers() ;
    generateMultiplyAndMultiply(8) ;
    generateMultiplayAndSimple(8) ;
}

string res ;

void relaxres(string t){
    if(t.length() < res.length()){
        res = t ;
    }
}

void check_plus(){
    for(int i = 1 ; i * 2 + 1 < res.length() ; ++i){
        for(long long x = 1 ; x <= ten[i] ; ++x){
            relaxres(getString(x) + "+" + getString(n - x)) ;
            if(n % x == 0){
                relaxres(getString(x) + "*" + getString(n / x)) ;
            }
        }
        for (auto x : record[i]){
            relaxres(getString(x) + "+" + getString(n - x)) ;
            if(n % x == 0){
                relaxres(getString(x) + "*" + getString(n / x)) ;
            }
        }
    }
}

int main(){

    cin >> n ;
    prepare() ;

    res = getString(n) ;

    check_plus() ;
    cout << res << endl ;

    return 0 ;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#include <string>
#include <sstream>
#include <set>

using namespace std ;

map <long long , string> dict ;
set <long long> record[10] ;

long long n ;
long long ten[11] ;

string toString(long long x){
    ostringstream os ;
    os << x ;
    return os.str() ;
}

int getlen(long long x){
    int t = 0 ;
    while(x){
        x /= 10 ;
        t += 1 ;
    }
    return (max(1 , t)) ;
}

void relax(long long x , string t){
    if(x > n || t.length() >= getlen(x)){
        return ;
    }
    if(dict.count(x) && dict[x].length() <= t.length()){
        return ;
    }
    //更新
    record[dict[x].length()].erase(x) ;
    dict[x] = t ;
    record[t.length()].insert(x) ;
}

string getString(long long x){
    if(dict.count(x)){
        return dict[x] ;
    }
    return toString(x) ;
}

void generatePowers(){
    for(long long x  = 2 ; x * x <= n; ++x){
        long long c = x * x ;
        int p = 2 ;
        while (c  <= n){
            string temp = toString(x) + "^" + toString(p) ;
            relax(c , temp) ;
            c *= x ;
            p += 1 ;
        }
    }
}

void generateMultiplyAndMultiply(int maxlen){
    for(int i = 1 ; i <= maxlen ; ++i){
        for(int j = i ; i + j + 1 <= maxlen ; ++j){
            for(auto x : record[i]){
                for (auto y : record[j]){
                    relax(x * y , getString(x) + "*" + getString(y)) ;
                }
            }
        }
    }
}

void generateMultiplayAndSimple(int maxlen){
    for(int i = 1 ; i <= maxlen ; ++i){
        for(long long x = 1 ; x < ten[maxlen - 1 - i] ; ++x){
            for (auto y : record[i]){
                relax(x * y , getString(y) + "*" + getString(x)) ;
            }
        }
    }
}

void prepare(){
    ten[0] = 1 ;
    for(int i = 1 ; i <= 10 ; ++i)
        ten[i] = 10 * ten[i - 1] ;
    generatePowers() ;
    generateMultiplyAndMultiply(7) ;
    generateMultiplayAndSimple(7) ;
}

string res ;

void relaxres(string t){
    if(t.length() < res.length()){
        res = t ;
    }
}

void check_plus(){
    for(int i = 1 ; i * 2 + 1 < res.length() ; ++i){
        for(long long x = 1 ; x <= ten[i] ; ++x){
            relaxres(getString(x) + "+" + getString(n - x)) ;
            if(n % x == 0){
                relaxres(getString(x) + "*" + getString(n / x)) ;
            }
        }
        for (auto x : record[i]){
            relaxres(getString(x) + "+" + getString(n - x)) ;
            if(n % x == 0){
                relaxres(getString(x) + "*" + getString(n / x)) ;
            }
        }
    }
}

int main(){

    cin >> n ;
    prepare() ;

    res = getString(n) ;
    //cout << res << endl ;

    check_plus() ;
    cout << res << endl ;
    //cout << toString(n) + "^2" << endl ;

    return 0 ;
}


#include <bits/stdc++.h>
using namespace std;

vector< vector<long long> > v;

long long numdigits(long long k) {
	int digits = 0; long long num = k;
	while (num > 0) {num /= 10; digits++;}
	return digits;
}

string minrepresentation(long long n) {
	string minstring = to_string(n); int minsize = minstring.size();
	for (long long k = 0; k < v.size(); k ++) {
		if (v[k][0] > sqrt(n)) break;
		for (long long l = 0; l < v[k].size(); l ++) {
			if (n % v[k][l] == 0) {
				string newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (newcheck.size() < minstring.size()) minstring = newcheck;
			}
			else {
				long long factor = n / v[k][l];
				string newcheck = to_string(factor) + "*" + to_string(k+2) + "^" + to_string(l+1);
				if (factor * v[k][l] == n) {
					if (newcheck.size() < minstring.size()) minstring = newcheck;
				}
				else {
					long long sum = n - (factor * v[k][l]);
					long long sumrep = minrepresentation(sum);
					newcheck += "+" + sumrep;
					if (newcheck.size() < minstring.size()) minstring = newcheck;
				}
			}
		}
	}
	return minstring;
}

int main() {
	long long n; cin >> n; string minstring = to_string(n);
	for (long long k = 2; k <= 10000; k ++) {
		vector<long long> v2;
		for (long long l = k; l <= 10000000000; l *= k) v2.push_back(l);
		v.push_back(v2);
	}
	cout << minrepresentation(n);
}


#include <bits/stdc++.h>
using namespace std;

vector< vector<long long> > v;

long long numdigits(long long k) {
	int digits = 0; long long num = k;
	while (num > 0) {num /= 10; digits++;}
	return digits;
}

string addrepresentation(long long n) {
	string minstring = to_string(n);
	if (numdigits(n) < 4) return minstring;
	for (long long k = 0; k < v.size(); k ++) {
		if (v[k][0] > sqrt(n)) break;
		for (long long l = 0; l < v[k].size(); l ++) {
			if (n == v[k][l]) {
				string newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (newcheck.size() < minstring.size()) minstring = newcheck;
			}
		}
	}
	return minstring;
}

string minrepresentation(long long n) {
	string minstring = to_string(n);
	if (n == 0) return "0";
	for (long long k = 0; k < v.size(); k ++) {
		if (v[k][0] > sqrt(n)) break;
		for (long long l = 0; l < v[k].size(); l ++) {
			if (n == v[k][l]) {
				string newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (newcheck.size() < minstring.size()) minstring = newcheck;
			}
			else {
				long long factor = n / v[k][l]; string newcheck;
				if (factor != 1) newcheck = to_string(factor) + "*" + to_string(k+2) + "^" + to_string(l+1);
				else newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (factor * v[k][l] == n) {
					if (newcheck.size() < minstring.size()) minstring = newcheck;
				}
				else {
					long long sum = n - (factor * v[k][l]);
					string minsumstring = addrepresentation(sum);
					newcheck += "+" + minsumstring;
					if (newcheck.size() < minstring.size()) minstring = newcheck;
				}
			}
		}
	}
	return minstring;
}

int main() {
	long long n; cin >> n; int a = 4; int b= 6;
	for (long long k = 2; k <= 10000; k ++) {
		vector<long long> v2;
		for (long long l = k; l <= 10000000000; l *= k) v2.push_back(l);
		v.push_back(v2);
	}
	cout << minrepresentation(n);
}


#include <bits/stdc++.h>
using namespace std;

vector< vector<long long> > v;

long long numdigits(long long k) {
	int digits = 0; long long num = k;
	while (num > 0) {num /= 10; digits++;}
	return digits;
}

string addrepresentation(long long n) {
	string minstring = to_string(n);
	if (numdigits(n) < 4) return minstring;
	for (long long k = 0; k < v.size(); k ++) {
		if (v[k][0] > sqrt(n)) break;
		for (long long l = 0; l < v[k].size(); l ++) {
			if (n == v[k][l]) {
				string newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (newcheck.size() < minstring.size()) minstring = newcheck;
			}
		}
	}
	return minstring;
}

string minrepresentation(long long n) {
	long long x = sqrt(n); string xstring = "99999999999"
	if (x * x == n) xstring = to_string(x) + "^" + to_string(2);
	string minstring = to_string(n);
	if (xstring.size() < minstring.size()) minstring = xstring;
	if (n == 0) return "0";
	for (long long k = 0; k < v.size(); k ++) {
		if (v[k][0] > sqrt(n)) break;
		for (long long l = 0; l < v[k].size(); l ++) {
			if (n == v[k][l]) {
				string newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (newcheck.size() < minstring.size()) minstring = newcheck;
			}
			else {
				long long factor = n / v[k][l]; string newcheck;
				if (factor != 1) newcheck = to_string(factor) + "*" + to_string(k+2) + "^" + to_string(l+1);
				else newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (factor * v[k][l] == n) {
					if (newcheck.size() < minstring.size()) minstring = newcheck;
				}
				else {
					long long sum = n - (factor * v[k][l]);
					string minsumstring = addrepresentation(sum);
					newcheck += "+" + minsumstring;
					if (newcheck.size() < minstring.size()) minstring = newcheck;
				}
			}
		}
	}
	return minstring;
}

int main() {
	long long n; cin >> n;
	for (long long k = 2; k <= 10000; k ++) {
		vector<long long> v2;
		for (long long l = k; l <= 10000000000; l *= k) v2.push_back(l);
		v.push_back(v2);
	}
	cout << minrepresentation(n);
}


#include <bits/stdc++.h>
using namespace std;

vector< vector<long long> > v;

long long numdigits(long long k) {
	int digits = 0; long long num = k;
	while (num > 0) {num /= 10; digits++;}
	return digits;
}

string addrepresentation(long long n) {
	string minstring = to_string(n);
	if (numdigits(n) < 4) return minstring;
	for (long long k = 0; k < v.size(); k ++) {
		if (v[k][0] > sqrt(n)) break;
		for (long long l = 0; l < v[k].size(); l ++) {
			if (n == v[k][l]) {
				string newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (newcheck.size() < minstring.size()) minstring = newcheck;
			}
		}
	}
	return minstring;
}

string minrepresentation(long long n) {
	long long x = sqrt(n); string xstring = "99999999999";
	if (x * x == n) xstring = to_string(x) + "^" + to_string(2);
	string minstring = to_string(n);
	if (xstring.size() < minstring.size()) minstring = xstring;
	if (n == 0) return "0";
	for (long long k = 0; k < v.size(); k ++) {
		if (v[k][0] > sqrt(n)) break;
		for (long long l = 0; l < v[k].size(); l ++) {
			if (n == v[k][l]) {
				string newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (newcheck.size() < minstring.size()) minstring = newcheck;
			}
			else {
				long long factor = n / v[k][l]; string newcheck;
				if (factor != 1) newcheck = addrepresentation(factor) + "*" + to_string(k+2) + "^" + to_string(l+1);
				else newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (factor * v[k][l] == n) {
					if (newcheck.size() < minstring.size()) minstring = newcheck;
				}
				else {
					long long sum = n - (factor * v[k][l]);
					string minsumstring = addrepresentation(sum);
					newcheck += "+" + minsumstring;
					if (newcheck.size() < minstring.size()) minstring = newcheck;
				}
			}
		}
	}
	return minstring;
}

int main() {
	long long n; cin >> n;
	for (long long k = 2; k <= 10000; k ++) {
		vector<long long> v2;
		for (long long l = k; l <= 10000000000; l *= k) v2.push_back(l);
		v.push_back(v2);
	}
	cout << minrepresentation(n);
}


#include <bits/stdc++.h>
using namespace std;

vector< vector<long long> > v;

long long numdigits(long long k) {
	int digits = 0; long long num = k;
	while (num > 0) {num /= 10; digits++;}
	return digits;
}

string addrepresentation(long long n) {
	string minstring = to_string(n);
	if (numdigits(n) < 4) return minstring;
	for (long long k = 0; k < v.size(); k ++) {
		if (v[k][0] > sqrt(n)) break;
		for (long long l = 0; l < v[k].size(); l ++) {
			if (n == v[k][l]) {
				string newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (newcheck.size() < minstring.size()) minstring = newcheck;
			}
		}
	}
	return minstring;
}

string minrepresentation(long long n) {
	string minstring = to_string(n);
	if (n == 0) return "0";
	for (long long k = 0; k < v.size(); k ++) {
		if (v[k][0] > sqrt(n)) break;
		for (long long l = 0; l < v[k].size(); l ++) {
			if (n == v[k][l]) {
				string newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (newcheck.size() < minstring.size()) minstring = newcheck;
			}
			else {
				long long factor = n / v[k][l]; string newcheck;
				if (factor != 1) newcheck = to_string(factor) + "*" + to_string(k+2) + "^" + to_string(l+1);
				else newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (factor * v[k][l] == n) {
					if (newcheck.size() < minstring.size()) minstring = newcheck;
				}
				else {
					long long sum = n - (factor * v[k][l]);
					string minsumstring = addrepresentation(sum);
					newcheck += "+" + minsumstring;
					if (newcheck.size() < minstring.size()) minstring = newcheck;
				}
			}
		}
	}
	return minstring;
}

int main() {
	long long n; cin >> n; int a = 4; int b= 6;
	for (long long k = 2; k <= 100000; k ++) {
		vector<long long> v2;
		for (long long l = k; l <= 10000000000; l *= k) v2.push_back(l);
		v.push_back(v2);
	}
	cout << minrepresentation(n);
}


#include <bits/stdc++.h>
using namespace std;

vector< vector<long long> > v;

long long numdigits(long long k) {
	int digits = 0; long long num = k;
	while (num > 0) {num /= 10; digits++;}
	return digits;
}

string addrepresentation(long long n) {
	string minstring = to_string(n);
	if (numdigits(n) < 4) return minstring;
	for (long long k = 0; k < v.size(); k ++) {
		if (v[k][0] > sqrt(n)) break;
		for (long long l = 0; l < v[k].size(); l ++) {
			if (n == v[k][l]) {
				string newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (newcheck.size() < minstring.size()) minstring = newcheck;
			}
		}
	}
	return minstring;
}

string minrepresentation(long long n, string minstring) {
	if (n == 0) return "0";
	for (long long k = 0; k < v.size(); k ++) {
		if (v[k][0] > sqrt(n)) break;
		for (long long l = 0; l < v[k].size(); l ++) {
			if (n == v[k][l]) {
				string newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (newcheck.size() < minstring.size()) minstring = newcheck;
			}
			else {
				long long factor = n / v[k][l]; string newcheck;
				if (factor != 1) newcheck = to_string(factor) + "*" + to_string(k+2) + "^" + to_string(l+1);
				else newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (factor * v[k][l] == n) {
					if (newcheck.size() < minstring.size()) minstring = newcheck;
				}
				else {
					long long sum = n - (factor * v[k][l]);
					string minsumstring = addrepresentation(sum);
					newcheck += "+" + minsumstring;
					if (newcheck.size() < minstring.size()) minstring = newcheck;
				}
			}
		}
	}
	return minstring;
}

int main() {
	long long n; cin >> n; long long x = sqrt(n); string minimumstring;
	if (x * x == n) minimumstring = to_string(x) + "^" + to_string(2);
	string nstring = to_string(n); string minstring;
	if (nstring.size() < minimumstring.size()) minstring = nstring;
	else minstring = minimumstring;
	for (long long k = 2; k <= 10000; k ++) {
		vector<long long> v2;
		for (long long l = k; l <= 10000000000; l *= k) v2.push_back(l);
		v.push_back(v2);
	}
	cout << minrepresentation(n, minstring);
}


#include <bits/stdc++.h>
using namespace std;

vector< vector<long long> > v;

long long numdigits(long long k) {
	int digits = 0; long long num = k;
	while (num > 0) {num /= 10; digits++;}
	return digits;
}

string addrepresentation(long long n) {
	string minstring = to_string(n);
	if (numdigits(n) < 4) return minstring;
	for (long long k = 0; k < v.size(); k ++) {
		if (v[k][0] > sqrt(n)) break;
		for (long long l = 0; l < v[k].size(); l ++) {
			if (n == v[k][l]) {
				string newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (newcheck.size() < minstring.size()) minstring = newcheck;
			}
		}
	}
	return minstring;
}

string minrepresentation(long long n) {
	long long x = sqrt(n); string xstring = "99999999999";
	if (x * x == n) xstring = to_string(x) + "^" + to_string(2);
	string minstring = to_string(n);
	if (xstring.size() < minstring.size()) minstring = xstring;
	if (n == 0) return "0";
	for (long long k = 0; k < v.size(); k ++) {
		if (v[k][0] > sqrt(n)) break;
		for (long long l = 0; l < v[k].size(); l ++) {
			if (n == v[k][l]) {
				string newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (newcheck.size() < minstring.size()) minstring = newcheck;
			}
			else {
				long long factor = n / v[k][l]; string newcheck;
				if (factor != 1) newcheck = to_string(factor) + "*" + to_string(k+2) + "^" + to_string(l+1);
				else newcheck = to_string(k+2) + "^" + to_string(l+1);
				if (factor * v[k][l] == n) {
					if (newcheck.size() < minstring.size()) minstring = newcheck;
				}
				else {
					long long sum = n - (factor * v[k][l]);
					string minsumstring = addrepresentation(sum);
					newcheck += "+" + minsumstring;
					if (newcheck.size() < minstring.size()) minstring = newcheck;
				}
			}
		}
	}
	return minstring;
}

int main() {
	long long n; cin >> n;
	for (long long k = 2; k <= 10000; k ++) {
		vector<long long> v2;
		for (long long l = k; l <= 10000000000; l *= k) v2.push_back(l);
		v.push_back(v2);
	}
	cout << minrepresentation(n);
}