#include<bits/stdc++.h>
using namespace std;
#define int long long
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define F first
#define S second
#define ld long double
int const M=(1<<20)+10,M2=1e7+10,mod=1e9+7,mod2=1e9+9,inf=1e9+30;
map<int,string>dp,dp2;
string x;
vector<pair<string,int> >ch;
bool flag=0;
int check(int l,int r)
{
	for(int i=l;i<=r;i++)
	{
		if(x[i]=='+')return check(l,i-1)+check(i+1,r);
	}
	for(int i=l;i<=r;i++)
	{
		if(x[i]=='*')return check(l,i-1)*check(i+1,r);
	}
	for(int i=l;i<=r;i++)
	{
		if(x[i]=='^')
		{
			int tmp=check(l,i-1);
			int tmp2=check(i+1,r);
			if(tmp==1)
				return 1;
			int now=1;
			for(int j=1;j<=tmp2;j++)
			{
				if(1e10/now<tmp)
				{
					flag=1;
					return 0;
				}
				now*=tmp;
			}
			return now;
		}
	}
	int t=0;
	for(int i=l;i<=r;i++)t*=10,t+=x[i]-'0';
	return t;
}
bool bad(string x)
{
	for(int i=0;i<x.size();i++)
	{
		if(x[i]=='+')return 1;
	}
	return 0;
}
string f(int tmp)
{
	string now="";
	while(tmp!=0)now+=char((tmp%10)+'0'),tmp/=10;
	reverse(now.begin(),now.end());
	return now;
}
void bt(int ind,bool last,bool vis)
{
	flag=0;
	int tmp;
	if(!last)
		 tmp=check(0,(int)x.size()-1);
	//if(x=="56")cout<<tmp<<endl;
	//cout<<tmp<<endl;
	if(!last && !flag && (dp[tmp].size()==0 || dp[tmp].size()>x.size()))dp[tmp]=x,ch.pb(mp(x,tmp));
	if(!last && !flag && (!vis && (!dp2[tmp].size() || dp2[tmp].size()>x.size())))dp2[tmp]=x;
	if(ind==6)
	{
		return;
	}
	string tm=x;
	for(int i=0;i<=9;i++)
	{
		if(last && i==0)continue;
		x+=char(i+'0');
		bt(ind+1,0,vis);
		x=tm;
	}
	if(last)return;
	x+='+';
	bt(ind+1,1,1);
	x=tm;
	x+='^';
	bt(ind+1,1,vis);
	x=tm;
	x+='*';
	bt(ind+1,1,vis);
	x=tm;
}
string mrg(string x,char tmp,string y)
{
	x+=tmp;
	for(int i=0;i<y.size();i++)x+=y[i];
	//if(x=="1*")cout<<x.size()<<" "<<y.size()<<endl;
	return x;
}
int32_t main()
{
	int n;
	cin>>n;
	bt(0,1,0);
	//x="10^9+7";
	//cout<<check(0,(int)x.size()-1)<<endl;
	string ans=f(n);
	if(dp[n].size())ans=dp[n];
	//cout<<dp2[56]<<endl;
	//cout<<ans<<endl;
	//cout<<dp[1000*1000*1000]<<endl;
	for(int i=0;i<ch.size();i++)
	{
		int tmp=ch[i].S;
		//if(ch[i].F=="9^8")cout<<ch[i].S<<" "<<n/tmp<<" "<<f(n/tmp)<<" "<<bad(ch[i].F)<<endl;
		if(tmp>n)continue;
		string hlp=dp[n-tmp];
		if(dp[n-tmp].size()==0)hlp=f(n-tmp);
		//if(tmp==1)cout<<hlp<<"*************"<<endl;
		if((int)hlp.size()+(int)ch[i].F.size()+1<ans.size())ans=mrg(ch[i].F,'+',hlp);
		if(bad(ch[i].F) || n%tmp!=0)continue;
		hlp=dp2[n/tmp];
		//if(tmp==1)cout<<dp2[n/tmp]<<endl;
		if(dp2[n/tmp].size()==0)hlp=f(n/tmp);
		//if(tmp==1)cout<<hlp<<"********"<<end
		if((int)hlp.size()+(int)ch[i].F.size()+1<ans.size())ans=mrg(ch[i].F,'*',hlp);

	}
	for(int i=2;i<=1e5;i++)
	{
		string tmp=f(i);
		int now=i,cnt=0;
		if(now%i!=0)continue;
		while(now<n){
			now*=i;
			cnt++;
		}
		if(now!=n)continue;
		string tm=f(cnt+1);
		if(tm.size()+tmp.size()+1<ans.size())ans=mrg(tmp,'^',tm);
	}
	cout<<ans;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define F first
#define S second
#define ld long double
int const M=(1<<20)+10,M2=1e7+10,mod=1e9+7,mod2=1e9+9,inf=1e9+30;
map<ll,string>dp,dp2;
string x;
vector<pair<string,ll> >ch;
bool flag=0;
ll check(int l,int r)
{
	int ind[3];
	ind[1]=-1,ind[2]=-1,ind[3]=-1;
	for(int i=l;i<=r;i++)
	{
		if(x[i]=='+')
		{
			ind[1]=i;
		}
		if(x[i]=='*')ind[2]=i;
		if(x[i]=='^')ind[3]=i;
	}
	if(ind[1]!=-1)return check(l,ind[1]-1)+check(ind[1]+1,r);
	if(ind[2]!=-1)return check(l,ind[2]-1)*check(ind[2]+1,r);
	if(ind[3]!=-1)
	{
			int i=ind[3];
			ll tmp=check(l,i-1);
			ll tmp2=check(i+1,r);
			if(tmp==1)
				return 1;
			ll now=1;
			for(int j=1;j<=tmp2;j++)
			{
				if(1e10/now<tmp)
				{
					flag=1;
					return 0;
				}
				now*=tmp;
			}
			return now;
	}
	ll t=0;
	for(int i=l;i<=r;i++)t*=10,t+=x[i]-'0';
	return t;
}
bool bad(string x)
{
	for(int i=0;i<x.size();i++)
	{
		if(x[i]=='+')return 1;
	}
	return 0;
}
string f(ll tmp)
{
	string now="";
	while(tmp!=0)now+=char((tmp%10)+'0'),tmp/=10;
	reverse(now.begin(),now.end());
	return now;
}
void bt(int ind,bool last,bool vis)
{
	flag=0;
	ll tmp;
	if(!last)
		 tmp=check(0,(int)x.size()-1);
	//if(x=="56")cout<<tmp<<endl;
	//cout<<tmp<<endl;
	if(!last && !flag && (dp[tmp].size()==0 || dp[tmp].size()>x.size()))dp[tmp]=x,ch.pb(mp(x,tmp));
	if(!last && !flag && (!vis && (!dp2[tmp].size() || dp2[tmp].size()>x.size())))dp2[tmp]=x;
	if(flag)return;
	if(ind==6)
	{
		return;
	}
	string tm=x;
	for(int i=0;i<=9;i++)
	{
		if(last && i==0)continue;
		x+=char(i+'0');
		bt(ind+1,0,vis);
		x=tm;
	}
	if(last)return;
	x+='+';
	bt(ind+1,1,1);
	x=tm;
	x+='^';
	bt(ind+1,1,vis);
	x=tm;
	x+='*';
	bt(ind+1,1,vis);
	x=tm;
}
string mrg(string x,char tmp,string y)
{
	x+=tmp;
	for(int i=0;i<y.size();i++)x+=y[i];
	//if(x=="1*")cout<<x.size()<<" "<<y.size()<<endl;
	return x;
}
int32_t main()
{
	ll n;
	cin>>n;
	bt(0,1,0);
	//x="10^9+7";
	//cout<<check(0,(int)x.size()-1)<<endl;
	string ans=f(n);
	if(dp[n].size())ans=dp[n];
	//cout<<dp2[56]<<endl;
	//cout<<ans<<endl;
	//cout<<dp[1000*1000*1000]<<endl;
	for(int i=0;i<ch.size();i++)
	{
		ll tmp=ch[i].S;
		ll res=n-tmp*(n/tmp);
		string hlp;
		if(res && res<10){
			string hlp=f(n/tmp);
			if(dp2[n/tmp].size()!=0)hlp=dp2[n/tmp];
			if(hlp.size()+ch[i].F.size()+2<ans.size()){ans=mrg(ch[i].F,'*',hlp);
				ans+='+';
				ans+=char(res+'0');
			}
		}
		if(tmp>n)continue;
		hlp=dp[n-tmp];
		if(dp[n-tmp].size()==0)hlp=f(n-tmp);
		if((int)hlp.size()+(int)ch[i].F.size()+1<ans.size())ans=mrg(ch[i].F,'+',hlp);
		if(bad(ch[i].F) || n%tmp!=0)continue;
		hlp=dp2[n/tmp];
		if(dp2[n/tmp].size()==0)hlp=f(n/tmp);
		if((int)hlp.size()+(int)ch[i].F.size()+1<ans.size())ans=mrg(ch[i].F,'*',hlp);

	}
	for(int i=2;i<=1e5;i++)
	{
		string tmp=f(i);
		ll now=(ll)i,cnt=0;
		while(now<n){
			now*=i;
			cnt++;
		}
		if(now!=n)continue;
		string tm=f(cnt+1);
		if(tm.size()+tmp.size()+1<ans.size())ans=mrg(tmp,'^',tm);
	}
	cout<<ans;
}


#include "omp.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <vector>
#include <cassert>
#include <fstream>
#include <algorithm>
#include <list>
#include <random>
#include <ctime>
#include <random>
#include <bitset>
#include <unordered_set>
#include <cassert>
#include <list>

using namespace std;

typedef long long ll;
typedef long double ld;

const int sze = 1e5, INF = 1e9 + 10, psze = 15;
ll power[psze] = { 1 };

int get(ll v)
{
	int l = 0, r = psze;
	while (r - l > 1)
	{
		int m = (l + r) >> 1;

		if (power[m] <= v)
			l = m;
		else
			r = m;
	}

	return l + 1;
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	for (int i = 1; i < psze; ++i)
		power[i] = power[i - 1] * 10;

	ll n;
	cin >> n;
	string ans = to_string(n);

	if (n == power[10])
	{
		cout << "100^5\n";
		return 0;
	}

	unordered_map<ll, string> trans;

	for (ll v = 2; v <= sze; ++v)
	{
		ll cur = v * v;
		int cnt = 2;

		while (cur <= n)
		{
			if (!trans[cur].size() || trans[cur].size() > get(v) + 1 + get(cnt))
				trans[cur] = to_string(v) + "^" + to_string(cnt);

			if (ans.size() > get(v) + 1 + get(cnt) + 1 + get(n - cur))
				ans = to_string(v) + "^" + to_string(cnt) + "+" + to_string(n - cur);

			if (!(n % cur) && ans.size() > get(v) + 1 + get(cnt) + 1 + get(n / cur))
				ans = to_string(v) + "^" + to_string(cnt) + "*" + to_string(n / cur);

			for (ll m = 2; get(v) + 1 + get(cnt) + 1 + get(m) + 1 + 1 < ans.size() && cur * m < n; ++m)
			{
				if (ans.size() > get(v) + 1 + get(cnt) + 1 + get(m) + 1 + get(n - cur * m))
					ans = to_string(v) + "^" + to_string(cnt) + "*" + to_string(m) + "+" + to_string(n - cur * m);
			}

			cur *= v;
			cnt++;
		}
	}

	if (trans.count(n) && ans.size() > trans[n].size())
		ans = trans[n];

	for (ll v = 2; v <= sze; ++v)
	{
		ll cur = v * v;
		int cnt = 2;

		while (cur <= n)
		{
			if (trans.count(n - cur) && ans.size() > get(v) + 1 + get(cnt) + 1 + trans[n - cur].size())
				ans = to_string(v) + "^" + to_string(cnt) + "+" + trans[n - cur];

			if (!(n % cur) && trans.count(n / cur) && ans.size() > get(v) + 1 + get(cnt) + 1 + trans[n / cur].size())
				ans = to_string(v) + "^" + to_string(cnt) + "*" + trans[n / cur];

			for (ll m = 1; get(v) + get(cnt) <= 4 && m < power[4 - get(v) - get(cnt)]; ++m)
			{
				if (trans.count(n - m - cur) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[n - m - cur].size())
					ans = to_string(m) + "+" + to_string(v) + "^" + to_string(cnt) + "+" + trans[n - m - cur];

				if (trans.count(n - m * cur) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[n - m * cur].size())
					ans = to_string(m) + "*" + to_string(v) + "^" + to_string(cnt) + "+" + trans[n - m * cur];

				if (!((n - m) % cur) && trans.count((n - m) / cur) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[(n - m) / cur].size())
					ans = to_string(m) + "+" + to_string(v) + "^" + to_string(cnt) + "*" + trans[(n - m) / cur];

				if (!(n % (cur * m)) && trans.count(n / (m * cur)) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[n / (m * cur)].size())
					ans = to_string(m) + "*" + to_string(v) + "^" + to_string(cnt) + "*" + trans[n / (m * cur)];
			}
			cur *= v;
			cnt++;
		}
	}

	cout << ans << '\n';

	return 0;
}


#include "omp.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <vector>
#include <cassert>
#include <fstream>
#include <algorithm>
#include <list>
#include <random>
#include <ctime>
#include <random>
#include <bitset>
#include <unordered_set>
#include <cassert>
#include <list>

using namespace std;

typedef long long ll;
typedef long double ld;

const int sze = 1e5, INF = 1e9 + 10, psze = 15;
ll power[psze] = { 1 };

int get(ll v)
{
	int l = 0, r = psze;
	while (r - l > 1)
	{
		int m = (l + r) >> 1;

		if (power[m] <= v)
			l = m;
		else
			r = m;
	}

	return l + 1;
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	for (int i = 1; i < psze; ++i)
		power[i] = power[i - 1] * 10;

	ll n;
	cin >> n;
	string ans = to_string(n);

	if (n == power[10])
	{
		cout << "100^5\n";
		return 0;
	}

	unordered_map<ll, string> trans;

	for (ll v = 2; v <= sze; ++v)
	{
		ll cur = v * v;
		int cnt = 2;

		while (cur <= n)
		{
			if (!trans[cur].size() || trans[cur].size() > get(v) + 1 + get(cnt))
				trans[cur] = to_string(v) + "^" + to_string(cnt);

			if (ans.size() > get(v) + 1 + get(cnt) + 1 + get(n - cur))
				ans = to_string(v) + "^" + to_string(cnt) + "+" + to_string(n - cur);

			if (!(n % cur) && ans.size() > get(v) + 1 + get(cnt) + 1 + get(n / cur))
				ans = to_string(v) + "^" + to_string(cnt) + "*" + to_string(n / cur);

			for (ll m = 2; get(v) + 1 + get(cnt) + 1 + get(m) + 1 + 1 < ans.size() && cur * m < n; ++m)
			{
				if (ans.size() > get(v) + 1 + get(cnt) + 1 + get(m) + 1 + get(n - cur * m))
					ans = to_string(v) + "^" + to_string(cnt) + "*" + to_string(m) + "+" + to_string(n - cur * m);
			}

			cur *= v;
			cnt++;
		}
	}

	for (ll v = 2; v <= sze; ++v)
	{
		ll cur = v * v;
		int cnt = 2;

		while (cur <= n)
		{
			for (ll m = 1; m < power[4 - get(v) - get(cnt)]; ++m)
			{
				if (trans.count(n - m - cur) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[n - m - cur].size())
					ans = to_string(m) + "+" + to_string(v) + "^" + to_string(cnt) + "+" + trans[n - m - cur];

				if (trans.count(n - m * cur) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[n - m * cur].size())
					ans = to_string(m) + "*" + to_string(v) + "^" + to_string(cnt) + "+" + trans[n - m * cur];

				if (!((n - m) % cur) && trans.count((n - m) / cur) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[(n - m) / cur].size())
					ans = to_string(m) + "+" + to_string(v) + "^" + to_string(cnt) + "*" + trans[(n - m) / cur];

				if (!(n % (cur * m)) && trans.count(n / (m * cur)) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[n / (m * cur)].size())
					ans = to_string(m) + "*" + to_string(v) + "^" + to_string(cnt) + "*" + trans[n / (m * cur)];
			}
			cur *= v;
			cnt++;
		}
	}

	cout << ans << '\n';

	return 0;
}


#include "omp.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <vector>
#include <cassert>
#include <fstream>
#include <algorithm>
#include <list>
#include <random>
#include <ctime>
#include <random>
#include <bitset>
#include <unordered_set>
#include <cassert>
#include <list>

using namespace std;

typedef long long ll;
typedef long double ld;

const int sze = 1e5, INF = 1e9 + 10, psze = 15;
ll power[psze] = { 1 };

int get(ll v)
{
	int l = 0, r = psze;
	while (r - l > 1)
	{
		int m = (l + r) >> 1;

		if (power[m] <= v)
			l = m;
		else
			r = m;
	}

	return l + 1;
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	for (int i = 1; i < psze; ++i)
		power[i] = power[i - 1] * 10;

	ll n;
	cin >> n;
	string ans = to_string(n);

	if (n == power[10])
	{
		cout << "100^5\n";
		return 0;
	}

	unordered_map<ll, string> trans;

	for (ll v = 2; v <= sze; ++v)
	{
		ll cur = v * v;
		int cnt = 2;

		while (cur <= n)
		{
			if (!trans[cur].size() || trans[cur].size() > get(v) + 1 + get(cnt))
				trans[cur] = to_string(v) + "^" + to_string(cnt);

			if (ans.size() > get(v) + 1 + get(cnt) + 1 + get(n - cur))
				ans = to_string(v) + "^" + to_string(cnt) + "+" + to_string(n - cur);

			if (!(n % cur) && ans.size() > get(v) + 1 + get(cnt) + 1 + get(n / cur))
				ans = to_string(v) + "^" + to_string(cnt) + "*" + to_string(n / cur);

			for (ll m = 2; get(v) + 1 + get(cnt) + 1 + get(m) + 1 + 1 < ans.size() && cur * m < n; ++m)
			{
				if (ans.size() > get(v) + 1 + get(cnt) + 1 + get(m) + 1 + get(n - cur * m))
					ans = to_string(v) + "^" + to_string(cnt) + "*" + to_string(m) + "+" + to_string(n - cur * m);
			}

			cur *= v;
			cnt++;
		}
	}

	for (ll v = 2; v <= sze; ++v)
	{
		ll cur = v * v;
		int cnt = 2;

		while (cur <= n)
		{
			if (trans.count(n - cur) && ans.size() > get(v) + 1 + get(cnt) + 1 + trans[n - cur].size())
				ans = to_string(v) + "^" + to_string(cnt) + "+" + trans[n - cur];

			if (!(n % cur) && trans.count(n / cur) && ans.size() + 1 + get(cnt) + 1 + trans[n / cur].size())
				ans = to_string(v) + "^" + to_string(cnt) + "*" + trans[n / cur];

			for (ll m = 1; m < power[4 - get(v) - get(cnt)]; ++m)
			{
				if (trans.count(n - m - cur) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[n - m - cur].size())
					ans = to_string(m) + "+" + to_string(v) + "^" + to_string(cnt) + "+" + trans[n - m - cur];

				if (trans.count(n - m * cur) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[n - m * cur].size())
					ans = to_string(m) + "*" + to_string(v) + "^" + to_string(cnt) + "+" + trans[n - m * cur];

				if (!((n - m) % cur) && trans.count((n - m) / cur) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[(n - m) / cur].size())
					ans = to_string(m) + "+" + to_string(v) + "^" + to_string(cnt) + "*" + trans[(n - m) / cur];

				if (!(n % (cur * m)) && trans.count(n / (m * cur)) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[n / (m * cur)].size())
					ans = to_string(m) + "*" + to_string(v) + "^" + to_string(cnt) + "*" + trans[n / (m * cur)];
			}
			cur *= v;
			cnt++;
		}
	}

	cout << ans << '\n';

	return 0;
}


#include "omp.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <vector>
#include <cassert>
#include <fstream>
#include <algorithm>
#include <list>
#include <random>
#include <ctime>
#include <random>
#include <bitset>
#include <unordered_set>
#include <cassert>
#include <list>

using namespace std;

typedef long long ll;
typedef long double ld;

const int sze = 1e5, INF = 1e9 + 10, psze = 15;
ll power[psze] = { 1 };

int get(ll v)
{
	int l = 0, r = psze;
	while (r - l > 1)
	{
		int m = (l + r) >> 1;

		if (power[m] <= v)
			l = m;
		else
			r = m;
	}

	return l + 1;
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	for (int i = 1; i < psze; ++i)
		power[i] = power[i - 1] * 10;

	ll n;
	cin >> n;
	string ans = to_string(n);

	if (n == power[10])
	{
		cout << "100^5\n";
		return 0;
	}

	unordered_map<ll, string> trans;

	for (ll v = 2; v <= sze; ++v)
	{
		ll cur = v * v;
		int cnt = 2;

		while (cur <= n)
		{
			if (!trans[cur].size() || trans[cur].size() > get(v) + 1 + get(cnt))
				trans[cur] = to_string(v) + "^" + to_string(cnt);

			if (ans.size() > get(v) + 1 + get(cnt) + 1 + get(n - cur))
				ans = to_string(v) + "^" + to_string(cnt) + "+" + to_string(n - cur);

			if (!(n % cur) && ans.size() > get(v) + 1 + get(cnt) + 1 + get(n / cur))
				ans = to_string(v) + "^" + to_string(cnt) + "*" + to_string(n / cur);

			for (ll m = 2; get(v) + 1 + get(cnt) + 1 + get(m) + 1 + 1 < ans.size() && cur * m < n; ++m)
			{
				if (ans.size() > get(v) + 1 + get(cnt) + 1 + get(m) + 1 + get(n - cur * m))
					ans = to_string(v) + "^" + to_string(cnt) + "*" + to_string(m) + "+" + to_string(n - cur * m);
			}

			cur *= v;
			cnt++;
		}
	}

	for (ll v = 2; v <= sze; ++v)
	{
		ll cur = v * v;
		int cnt = 2;

		while (cur <= n)
		{
			if (trans.count(n - cur) && ans.size() > get(v) + 1 + get(cnt) + 1 + trans[n - cur].size())
				ans = to_string(v) + "^" + to_string(cnt) + "+" + trans[n - cur];

			if (!(n % cur) && trans.count(n / cur) && ans.size() > get(v) + 1 + get(cnt) + 1 + trans[n / cur].size())
				ans = to_string(v) + "^" + to_string(cnt) + "*" + trans[n / cur];

			for (ll m = 1; m < power[4 - get(v) - get(cnt)]; ++m)
			{
				if (trans.count(n - m - cur) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[n - m - cur].size())
					ans = to_string(m) + "+" + to_string(v) + "^" + to_string(cnt) + "+" + trans[n - m - cur];

				if (trans.count(n - m * cur) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[n - m * cur].size())
					ans = to_string(m) + "*" + to_string(v) + "^" + to_string(cnt) + "+" + trans[n - m * cur];

				if (!((n - m) % cur) && trans.count((n - m) / cur) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[(n - m) / cur].size())
					ans = to_string(m) + "+" + to_string(v) + "^" + to_string(cnt) + "*" + trans[(n - m) / cur];

				if (!(n % (cur * m)) && trans.count(n / (m * cur)) && ans.size() > get(m) + 1 + get(v) + 1 + get(cnt) + 1 + trans[n / (m * cur)].size())
					ans = to_string(m) + "*" + to_string(v) + "^" + to_string(cnt) + "*" + trans[n / (m * cur)];
			}
			cur *= v;
			cnt++;
		}
	}

	cout << ans << '\n';

	return 0;
}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define sf scanf
#define pf printf
#define pb push_back
#define mp make_pair
#define PI ( acos(-1.0) )
#define mod 1000000007LL
#define IN freopen("C.in","r",stdin)
#define OUT freopen("output.txt","w",stdout)
#define FOR(i,a,b) for(i=a ; i<=b ; i++)
#define DBG pf("Hi\n")
#define INF 1000000000
#define i64 long long int
#define eps (1e-8)
#define xx first
#define yy second
#define ln 17
#define off 2

using namespace __gnu_pbds;
using namespace std ;

typedef tree< i64, null_type, less<i64>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
typedef pair<i64, i64> pii;

#define maxn 200000

map <i64,i64> M ;
map <i64, pair<i64,i64> > P ;

string f( int e,int a, int cnta,int b,int cntb ,string s1 , string s2 )
{
    a += '0' ; cnta += '0' ; cntb += '0' ; b +='0' ;e+='0' ;
    string ans = "" ;
    ans+= e ; ans += s1 ; ans += a ; ans += "^" ; ans += cnta ; ans+=s2 ; ans += b ; ans +="^" ; ans+= cntb ;
    return ans ;
}

i64 numLen(i64 n)
{
    if(n<10) return 1 ;
    i64 ans = 0 ;
    while(n!=0)
    {
        n /= 10 ;
        ans++ ;
    }
    return ans ;
}

string toString(i64 n)
{
    string ans = "" ;
    while(n!=0 )
    {
        ans += ( n%10 + '0' ) ;
        n /= 10 ;
    }
    for(int i=0, j = (int)ans.size() - 1 ; i<j ; i++,j--)
    {
        char temp = ans[i] ;
        ans[i] = ans[j] ;
        ans[j] = temp ;
    }
    return ans ;
}
string res ;

int main()
{
    i64 i, j, k, l, m, n ;

    scanf("%lld",&n) ;

    i64 ans = numLen(n) ;
    res = toString(n) ;

    for(i=2 ; i*i<=n ; i++)
    {
        i64 j = i ;
        i64 cnt = 1 ;
        while( j*i <= n )
        {
            j = j*i ;
            cnt++ ;
            i64 k = numLen(i) + 1 + numLen(cnt) ;
            if(j==n)
            {
                if( k<ans )
                {
                    ans = k ;
                    res = toString(i) ;
                    res += "^" ;
                    res += toString(cnt) ;
                }
            }
            if( M.find( j )==M.end() )
            {
                M[j] = k ;
                P[j] = mp(i,cnt) ;
            }
            else
            {
                if( M[j] > k )
                {
                    M[j] = k ;
                    P[j] = mp(i,cnt) ;
                }
            }
            if( n%j==0 )
            {
                i64 l1 = numLen(n/j) ;
                if( k+l1+1 <ans )
                {
                    ans = k+l1+1 ;
                    res = toString(i) ;
                    res += "^" ;
                    res += toString(cnt) ;
                    res += "*" ;
                    res += toString(n/j) ;
                }
                if( M.find( n/j )!=M.end() && k+M[n/j]+1 < ans )
                {
                    ans = k+M[n/j]+1 ;
                    res = toString(i) ;
                    res +="^" ;
                    res+=toString(cnt) ;
                    res +="*" ;
                    res += toString( P[n/j].first ) ;
                    res+= "^" ;
                    res += toString( P[n/j].second ) ;
                }
            }
            if( k+numLen(n-j)+1 < ans )
            {
                ans = k+numLen(n-j)+1 ;
                res = toString(i) ;
                res +="^" ;
                res+=toString(cnt) ;
                res += "+" ;
                res += toString(n-j) ;
            }
            if( M.find( n-j )!=M.end() && k+M[n-j]+1 < ans )
            {
                ans = k+M[n-j]+1 ;
                res = toString(i) ;
                res +="^" ;
                res+=toString(cnt) ;
                res +="+" ;
                res += toString( P[n-j].first ) ;
                res+= "^" ;
                res += toString( P[n-j].second ) ;
            }
        }
    }

    for(int i =1 ; i<1000 ; i++)
    {
        for(int j=1; j<1000 ; j++)
        {
            if( (n-i)%j == 0 )
            {
                if( M.find((n-i)/j) != M.end() && numLen(i)+numLen(j)+2+M[(n-i)/j] < ans  )
                {
                    res = "" ;
                    res += toString(i) ;
                    res += "+" ;
                    res += toString(j) ;
                    res += "*" ;
                    k = (n-i)/j ;
                    res += toString(P[k].first) ;
                    res +=  "^" ;
                    res += toString(P[k].second) ;
                    ans = numLen(i)+numLen(j)+2+M[(n-i)/j] ;
                }
            }
        }
    }

  //  DBG ;
    if( ans>9 )
    {
        for( int e = 1 ; e<=9 ; e++ )
        {
            for(int a = 1 ; a<=9 ; a++)
            {
                int cnta = 1 ;
                for(i64 ap = a ; cnta<=9 ; ap*=a, cnta++)
                {
                    for(int b = 1 ; b<=9 ; b++)
                    {
                        int cntb = 1 ;
                        for(i64 bp = b ; cntb<=9 ; bp*=b, cntb++)
                        {
                            if( e*ap+bp == n ) res = f(e,a,cnta,b,cntb,"*","+") ;
                            if( e*ap*bp == n ) res = f(e,a,cnta,b,cntb,"*","*") ;
                            if( e+ap*bp == n ) res = f(e,a,cnta,b,cntb,"+","*") ;
                        }
                    }
                }
            }
        }
    }

    cout<<res<<endl ;

    return 0 ;
}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define sf scanf
#define pf printf
#define pb push_back
#define mp make_pair
#define PI ( acos(-1.0) )
#define mod 1000000007LL
#define IN freopen("C.in","r",stdin)
#define OUT freopen("output.txt","w",stdout)
#define FOR(i,a,b) for(i=a ; i<=b ; i++)
#define DBG pf("Hi\n")
#define INF 1000000000
#define i64 long long int
#define eps (1e-8)
#define xx first
#define yy second
#define ln 17
#define off 2

using namespace __gnu_pbds;
using namespace std ;

typedef tree< i64, null_type, less<i64>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
typedef pair<i64, i64> pii;

#define maxn 200000

map <i64,i64> M ;
map <i64, pair<i64,i64> > P ;

string f( int e,int a, int cnta,int b,int cntb ,string s1 , string s2 )
{
    a += '0' ; cnta += '0' ; cntb += '0' ; b +='0' ;e+='0' ;
    string ans = "" ;
    ans+= e ; ans += s1 ; ans += a ; ans += "^" ; ans += cnta ; ans+=s2 ; ans += b ; ans +="^" ; ans+= cntb ;
    return ans ;
}

i64 numLen(i64 n)
{
    if(n<10) return 1 ;
    i64 ans = 0 ;
    while(n!=0)
    {
        n /= 10 ;
        ans++ ;
    }
    return ans ;
}

string toString(i64 n)
{
    string ans = "" ;
    while(n!=0 )
    {
        ans += ( n%10 + '0' ) ;
        n /= 10 ;
    }
    for(int i=0, j = (int)ans.size() - 1 ; i<j ; i++,j--)
    {
        char temp = ans[i] ;
        ans[i] = ans[j] ;
        ans[j] = temp ;
    }
    return ans ;
}
string res ;

int main()
{
    i64 i, j, k, l, m, n ;

    scanf("%lld",&n) ;

    i64 ans = numLen(n) ;
    res = toString(n) ;

    for(i=2 ; i*i<=n ; i++)
    {
        i64 j = i ;
        i64 cnt = 1 ;
        while( j*i <= n )
        {
            j = j*i ;
            cnt++ ;
            i64 k = numLen(i) + 1 + numLen(cnt) ;
            if(j==n)
            {
                if( k<ans )
                {
                    ans = k ;
                    res = toString(i) ;
                    res += "^" ;
                    res += toString(cnt) ;
                }
            }
            if( M.find( j )==M.end() )
            {
                M[j] = k ;
                P[j] = mp(i,cnt) ;
            }
            else
            {
                if( M[j] > k )
                {
                    M[j] = k ;
                    P[j] = mp(i,cnt) ;
                }
            }
            if( n%j==0 )
            {
                i64 l1 = numLen(n/j) ;
                if( k+l1 <ans )
                {
                    ans = k+l1 ;
                    res = toString(i) ;
                    res += "^" ;
                    res += toString(cnt) ;
                    res += "*" ;
                    res += toString(n/j) ;
                }
                if( M.find( n/j )!=M.end() && k+M[n/j] < ans )
                {
                    ans = k+M[n/j] ;
                    res = toString(i) ;
                    res +="^" ;
                    res+=toString(cnt) ;
                    res +="*" ;
                    res += toString( P[n/j].first ) ;
                    res+= "^" ;
                    res += toString( P[n/j].second ) ;
                }
            }
            if( k+numLen(n-j) < ans )
            {
                ans = k+numLen(n-j) ;
                res = toString(i) ;
                res +="^" ;
                res+=toString(cnt) ;
                res += "+" ;
                res += toString(n-j) ;
            }
            if( M.find( n-j )!=M.end() && k+M[n-j] < ans )
            {
                ans = k+M[n-j] ;
                res = toString(i) ;
                res +="^" ;
                res+=toString(cnt) ;
                res +="+" ;
                res += toString( P[n-j].first ) ;
                res+= "^" ;
                res += toString( P[n-j].second ) ;
            }
        }
    }

    for(int i =1 ; i<1000 ; i++)
    {
        for(int j=1; j<1000 ; j++)
        {
            if( (n-i)%j == 0 )
            {
                if( M.find((n-i)/j) != M.end() && numLen(i)+numLen(j)+2+M[(n-i)/j] < ans  )
                {
                    res = "" ;
                    res += toString(i) ;
                    res += "+" ;
                    res += toString(j) ;
                    res += "*" ;
                    k = (n-i)/j ;
                    res += toString(P[k].first) ;
                    res +=  "^" ;
                    res += toString(P[k].second) ;
                    ans = numLen(i)+numLen(j)+2+M[(n-i)/j] ;
                }
            }
        }
    }

  //  DBG ;
    if( ans>9 )
    {
        for( int e = 1 ; e<=9 ; e++ )
        {
            for(int a = 1 ; a<=9 ; a++)
            {
                int cnta = 1 ;
                for(i64 ap = a ; cnta<=9 ; ap*=a, cnta++)
                {
                    for(int b = 1 ; b<=9 ; b++)
                    {
                        int cntb = 1 ;
                        for(i64 bp = b ; cntb<=9 ; bp*=b, cntb++)
                        {
                            if( e*ap+bp == n ) res = f(e,a,cnta,b,cntb,"*","+") ;
                            if( e*ap*bp == n ) res = f(e,a,cnta,b,cntb,"*","*") ;
                            if( e+ap*bp == n ) res = f(e,a,cnta,b,cntb,"+","*") ;
                        }
                    }
                }
            }
        }
    }

    cout<<res<<endl ;

    return 0 ;
}


// who's it from?
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define f first
#define s second
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()

ll n;
vector<pair<ll,string> > po;

int32_t main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int base = 2; base <= 100000; base++) {
		ll val = base;
		string s = to_string(base) + '^';
		for (int e = 2; val * base <= 10000000000; e++) {
			val *= base;
			po.emplace_back(val, s + to_string(e));
		}
	}
	//for (ll n = 1; n <= 10000; n++) {
	string res = to_string(n);
	for (ll x = 1; x * x <= n; x++) {
		if (x * (n / x) == n) {
			string tmp = to_string(x) + '*' + to_string(n / x);
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
		}
	}
	for (const pair<ll,string> &p : po) {
		if (n >= p.f) {
			string tmp = p.s;
			if (n - p.f != 0) {
				tmp += '+';
				tmp += to_string(n - p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
			ll c = n / p.f;
			int d = 0;
			ll asdf = c;
			while (asdf) {
				d++;
				asdf /= 10;
			}
			ll num = 0;
			for (int i = 1; i < d; i++) {
				num = num * 10 + 9;
				tmp = to_string(num) + '*' + p.s;
				assert(n - num * p.f >= 0);
				if (n - num * p.f != 0) {
					tmp += '+';
					tmp += to_string(n - num * p.f);
				}
				if (SZ(tmp) < SZ(res)) {
					res = tmp;
				}
			}
			tmp = to_string(c) + '*' + p.s;
			if (n - c * p.f != 0) {
				tmp += '+';
				tmp += to_string(n - c * p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
		}
	}
	//cout << n << ' ';
	cout << res << endl;
	//}
	return 0;
}


// who's it from?
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define f first
#define s second
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()

ll n;
vector<pair<ll,string> > po;
map<ll, string> mp;

int32_t main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int base = 2; base <= 100000; base++) {
		ll val = base;
		string s = to_string(base) + '^';
		for (int e = 2; val * base <= 10000000000ll; e++) {
			val *= base;
			po.emplace_back(val, s + to_string(e));
			if(mp.count(val) && SZ(s + to_string(e)) < SZ(mp[val])) {
				mp[val] = s + to_string(e);
			} else if (!mp.count(val)) {
				mp[val] = s + to_string(e);
			}
		}
	}
	//for (ll n = 1; n <= 10000; n++) {
	string res = to_string(n);
	for (const pair<ll,string> &p : po) {
		if (n >= p.f) {
			if (mp.count(n - p.f)) {
				string tmp = p.s + '+' + mp[n - p.f];
				if (SZ(tmp) < SZ(res)) {
					res = tmp;
				}
			}
			for (int i = 0; i < 10; i++) {

				if ((n - i) % p.f == 0 && mp.count((n - i) / p.f)) {
					string tmp = p.s + '*' + mp[(n - i) / p.f];
					if (i != 0) {
						tmp += '+';
						tmp += to_string(i);
					}
					if (SZ(tmp) < SZ(res)) {
						res = tmp;
					}
				}
			}
			string tmp = p.s;
			if (n - p.f != 0) {
				tmp += '+';
				tmp += to_string(n - p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
			ll c = n / p.f;
			int d = 0;
			ll asdf = c;
			while (asdf) {
				d++;
				asdf /= 10;
			}
			ll num = 0;
			for (int i = 1; i < d; i++) {
				num = num * 10 + 9;
				tmp = to_string(num) + '*' + p.s;
				assert(n - num * p.f >= 0);
				if (n - num * p.f != 0) {
					tmp += '+';
					tmp += to_string(n - num * p.f);
				}
				if (SZ(tmp) < SZ(res)) {
					res = tmp;
				}
			}
			tmp = to_string(c) + '*' + p.s;
			if (n - c * p.f != 0) {
				tmp += '+';
				tmp += to_string(n - c * p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
		}
	}
	//cout << n << ' ';
	cout << res << endl;
	//}
	return 0;
}


// who's it from?
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define f first
#define s second
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()

ll n;
vector<pair<ll,string> > po;
map<ll, string> mp;

int32_t main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int base = 2; base <= 100000; base++) {
		ll val = base;
		string s = to_string(base) + '^';
		for (int e = 2; val * base <= 10000000000ll; e++) {
			val *= base;
			po.emplace_back(val, s + to_string(e));
			if(mp.count(val) && SZ(s + to_string(e)) < SZ(mp[val])) {
				mp[val] = s + to_string(e);
			} else if (!mp.count(val)) {
				mp[val] = s + to_string(e);
			}
		}
	}
	//for (ll n = 1; n <= 10000; n++) {
	string res = to_string(n);
	for (const pair<ll,string> &p : po) {
		if (n >= p.f) {
			if (mp.count(n - p.f)) {
				string tmp = p.s + '+' + mp[n - p.f];
				if (SZ(tmp) < SZ(res)) {
					res = tmp;
				}
			}
			if (n % p.f == 0 && mp.count(n / p.f)) {
				string tmp = p.s + '*' + mp[n / p.f];
				if (SZ(tmp) < SZ(res)) {
					res = tmp;
				}
			}
			string tmp = p.s;
			if (n - p.f != 0) {
				tmp += '+';
				tmp += to_string(n - p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
			ll c = n / p.f;
			int d = 0;
			ll asdf = c;
			while (asdf) {
				d++;
				asdf /= 10;
			}
			ll num = 0;
			for (int i = 1; i < d; i++) {
				num = num * 10 + 9;
				tmp = to_string(num) + '*' + p.s;
				assert(n - num * p.f >= 0);
				if (n - num * p.f != 0) {
					tmp += '+';
					tmp += to_string(n - num * p.f);
				}
				if (SZ(tmp) < SZ(res)) {
					res = tmp;
				}
			}
			tmp = to_string(c) + '*' + p.s;
			if (n - c * p.f != 0) {
				tmp += '+';
				tmp += to_string(n - c * p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
		}
	}
	//cout << n << ' ';
	cout << res << endl;
	//}
	return 0;
}


// who's it from?
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define f first
#define s second
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()

ll n;
vector<pair<ll,string> > po;

int32_t main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int base = 2; base <= 100000; base++) {
		ll val = base;
		string s = to_string(base) + '^';
		for (int e = 2; val * base <= 10000000000ll; e++) {
			val *= base;
			po.emplace_back(val, s + to_string(e));
		}
	}
	//for (ll n = 1; n <= 10000; n++) {
	string res = to_string(n);
	for (const pair<ll,string> &p : po) {
		if (n >= p.f) {
			string tmp = p.s;
			if (n - p.f != 0) {
				tmp += '+';
				tmp += to_string(n - p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
			ll c = n / p.f;
			int d = 0;
			ll asdf = c;
			while (asdf) {
				d++;
				asdf /= 10;
			}
			ll num = 0;
			for (int i = 1; i < d; i++) {
				num = num * 10 + 9;
				tmp = to_string(num) + '*' + p.s;
				//if (num == 999)cout << tmp << endl;
				assert(n - num * p.f >= 0);
				if (n - num * p.f != 0) {
					tmp += '+';
					tmp += to_string(n - num * p.f);
				}
				if (SZ(tmp) < SZ(res)) {
					res = tmp;
				}
			}
			tmp = to_string(c) + '*' + p.s;
			if (n - c * p.f != 0) {
				tmp += '+';
				tmp += to_string(n - c * p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
		}
	}
	//cout << n << ' ';
	cout << res << endl;
	//}
	return 0;
}


// who's it from?
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define f first
#define s second
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()

ll n;
vector<pair<ll,string> > po;
map<ll, string> mp;

int32_t main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int base = 2; base <= 100000; base++) {
		ll val = base;
		string s = to_string(base) + '^';
		for (int e = 2; val * base <= 10000000000ll; e++) {
			val *= base;
			po.emplace_back(val, s + to_string(e));
			if(mp.count(val) && SZ(s + to_string(e)) < SZ(mp[val])) {
				mp[val] = s + to_string(e);
			} else if (!mp.count(val)) {
				mp[val] = s + to_string(e);
			}
		}
	}
	//for (ll n = 1; n <= 10000; n++) {
	string res = to_string(n);
	for (const pair<ll,string> &p : po) {
		if (n >= p.f) {
			if (mp.count(n - p.f)) {
				string tmp = p.s + '+' + mp[n - p.f];
				if (SZ(tmp) < SZ(res)) {
					res = tmp;
				}
			}
			for (int i = 0; i < 10; i++) {
				if ((n - i) % p.f == 0 && mp.count((n - i) / p.f)) {
					string tmp = p.s + '*' + mp[(n - i) / p.f];
					if (i != 0) {
						tmp += '+';
						tmp += to_string(i);
					}
					if (SZ(tmp) < SZ(res)) {
						res = tmp;
					}
				}

			}
			for (int i = 2; i < 10; i++) {
				if (p.f * i <= n) {
					if (mp.count(n - p.f * i)) {
						string tmp = p.s + '*' + to_string(i) + '+' + mp[n - p.f * i];
						if (SZ(tmp) < SZ(res)) {
							res = tmp;
						}
					}
					if (n % (p.f * i) == 0) {
						if (mp.count(n / p.f / i)) {
							string tmp = p.s + '*' + to_string(i) + '*' + mp[n - p.f * i];
							if (SZ(tmp) < SZ(res)) {
								res = tmp;
							}
						}
					}
				}
			}
			string tmp = p.s;
			if (n - p.f != 0) {
				tmp += '+';
				tmp += to_string(n - p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
			ll c = n / p.f;
			int d = 0;
			ll asdf = c;
			while (asdf) {
				d++;
				asdf /= 10;
			}
			ll num = 0;
			for (int i = 1; i < d; i++) {
				num = num * 10 + 9;
				tmp = to_string(num) + '*' + p.s;
				assert(n - num * p.f >= 0);
				if (n - num * p.f != 0) {
					tmp += '+';
					tmp += to_string(n - num * p.f);
				}
				if (SZ(tmp) < SZ(res)) {
					res = tmp;
				}
			}
			tmp = to_string(c) + '*' + p.s;
			if (n - c * p.f != 0) {
				tmp += '+';
				tmp += to_string(n - c * p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
		}
	}
	//cout << n << ' ';
	cout << res << endl;
	//}
	return 0;
}


// who's it from?
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define f first
#define s second
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()

ll n;
vector<pair<ll,string> > po;

int32_t main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int base = 2; base <= 100000; base++) {
		ll val = base;
		string s = to_string(base) + '^';
		for (int e = 2; val * base <= 10000000000; e++) {
			val *= base;
			po.emplace_back(val, s + to_string(e));
		}
	}
	//for (ll n = 1; n <= 10000; n++) {
	string res = to_string(n);
	for (ll x = 1; x * x <= n; x++) {
		if (x * (n / x) == n) {
			string tmp = to_string(x) + '*' + to_string(n / x);
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
		}
	}
	for (const pair<ll,string> &p : po) {
		if (n >= p.f) {
			string tmp = p.s;
			if (n - p.f != 0) {
				tmp += '+';
				tmp += to_string(n - p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
			ll c = n / p.f;
			tmp = to_string(c) + '*' + p.s;
			if (n - c * p.f != 0) {
				tmp += '+';
				tmp += to_string(n - c * p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
		}
	}
	//cout << n << ' ';
	cout << res << endl;
	//}
	return 0;
}


// who's it from?
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define f first
#define s second
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()

ll n;
vector<pair<ll,string> > po;

int32_t main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int base = 2; base <= 100000; base++) {
		ll val = base;
		string s = to_string(base) + '^';
		for (int e = 2; val * base <= 10000000000; e++) {
			val *= base;
			po.emplace_back(val, s + to_string(e));
		}
	}
	string res = to_string(n);
	for (const pair<ll,string> &p : po) {
		if (n >= p.f) {
			string tmp = p.s;
			if (n - p.f != 0) {
				tmp += '+';
				tmp += to_string(n - p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
			ll c = n / p.f;
			tmp = to_string(c) + '*' + p.s;
			if (n - c * p.f != 0) {
				tmp += '+';
				tmp += to_string(n - c * p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
		}
	}
	cout << res << endl;
	return 0;
}


// who's it from?
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define f first
#define s second
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()

ll n;
vector<pair<ll,string> > po;
map<ll, string> mp;

int32_t main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int base = 2; base <= 100000; base++) {
		ll val = base;
		string s = to_string(base) + '^';
		for (int e = 2; val * base <= 10000000000ll; e++) {
			val *= base;
			po.emplace_back(val, s + to_string(e));
			if(mp.count(val) && SZ(s + to_string(e)) < SZ(mp[val])) {
				mp[val] = s + to_string(e);
			} else if (!mp.count(val)) {
				mp[val] = s + to_string(e);
			}
		}
	}
	//for (ll n = 1; n <= 10000; n++) {
	string res = to_string(n);
	for (const pair<ll,string> &p : po) {
		if (n >= p.f) {
			if (mp.count(n - p.f)) {
				string tmp = p.s + '+' + mp[n - p.f];
				if (SZ(tmp) < SZ(res)) {
					res = tmp;
				}
			}
			for (int i = 0; i < 10; i++) {
				if ((n - i) % p.f == 0 && mp.count((n - i) / p.f)) {
					string tmp = p.s + '*' + mp[(n - i) / p.f];
					if (i != 0) {
						tmp += '+';
						tmp += to_string(i);
					}
					if (SZ(tmp) < SZ(res)) {
						res = tmp;
					}
				}

			}
			for (int i = 2; i < 10; i++) {
				if (p.f * i <= n) {
					if (mp.count(n - p.f * i)) {
						string tmp = p.s + '*' + to_string(i) + '+' + mp[n - p.f * i];
						if (SZ(tmp) < SZ(res)) {
							res = tmp;
						}
					}
					if (n % (p.f * i) == 0) {
						if (mp.count(n / (p.f * i))) {
							string tmp = p.s + '*' + to_string(i) + '*' + mp[n / (p.f * i)];
							if (SZ(tmp) < SZ(res)) {
								res = tmp;
							}
						}
					}
				}
			}
			string tmp = p.s;
			if (n - p.f != 0) {
				tmp += '+';
				tmp += to_string(n - p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
			ll c = n / p.f;
			int d = 0;
			ll asdf = c;
			while (asdf) {
				d++;
				asdf /= 10;
			}
			ll num = 0;
			for (int i = 1; i < d; i++) {
				num = num * 10 + 9;
				tmp = to_string(num) + '*' + p.s;
				assert(n - num * p.f >= 0);
				if (n - num * p.f != 0) {
					tmp += '+';
					tmp += to_string(n - num * p.f);
				}
				if (SZ(tmp) < SZ(res)) {
					res = tmp;
				}
			}
			tmp = to_string(c) + '*' + p.s;
			if (n - c * p.f != 0) {
				tmp += '+';
				tmp += to_string(n - c * p.f);
			}
			if (SZ(tmp) < SZ(res)) {
				res = tmp;
			}
		}
	}
	//cout << n << ' ';
	cout << res << endl;
	//}
	return 0;
}


#include <iostream>
#include <cmath>

using namespace std;

int  main() {
    string s , z = "";
    long long  n;
    cin>>n;
    s = to_string(n);
    long long  l = s.size();
    if(l <= 4)return cout<<s,0;
    for(long long  i = 0; i < 2; ++i){
       z += s[i];

    }
    long long  zz = atoll(z.c_str());
    long long  x = zz / 10;
    long long  m = n - pow(zz, l - 1);
    if(m > 0){
      if(x == 1){
         cout<<z<<"^"<<l - 1<<"+"<<m;
      }
      else {
        cout<<x<<"*"<<z<<"^"<<l - 1 <<"+"<<m;
      }
    }
   else{
      if(x == 1){
        cout<<z<<"^"<<l - 1;
      }
      else{
        cout<<x<<"*"<<z<<"^"<<l - 1;
      }
    }
    //cout<<s;
}


#include <iostream>
#include <cmath>

using namespace std;

int main() {
    string s , z = "";
    int n;
    cin>>n;
    s = to_string(n);
    int l = s.size();
    if(l <= 4)return cout<<s,0;
    for(int i = 0; i < 2; ++i){
       z += s[i];
    }
    int zz = atoi(z.c_str());
    int x = zz / 10;
    int m = n - pow(zz, l - 1);
    if(m > 0){
      if(x == 1){
         cout<<z<<"^"<<l - 1<<"+"<<m;
      }
      else {
        cout<<x<<"*"<<z<<"^"<<l - 1 <<"+"<<m;
      }
    }
    else{
      if(x == 1){
        cout<<z<<"^"<<l - 1;
      }
      else{
        cout<<x<<"*"<<z<<"^"<<l - 1;
      }
    }

}


#include <iostream>
#include <cmath>

using namespace std;

int  main() {
    string s , z = "";
    long long  n;
    cin>>n;
    s = to_string(n);
    long long  l = s.size();
    if(l <= 4)return cout<<s,0;
    for(long long  i = 0; i < 2; ++i){
       z += s[i];

    }
    long long  zz = atoll(z.c_str());
    long long  x = zz / 10;
    long long  m = n - pow(zz, l - 1);
    if(m > 0){
      if(x == 1){
         cout<<z<<"^"<<l - 1<<"+"<<m;
      }
      else {
        cout<<x<<"*"<<10<<"^"<<l - 1 <<"+"<<m;
      }
    }
   else{
      if(x == 1){
        cout<<z<<"^"<<l - 1;
      }
      else{
        cout<<x<<"*"<<10<<"^"<<l - 1;
      }
    }
    //cout<<s;
}


#include <iostream>
#include <cmath>
#include <map>

using namespace std;

map<long long , string >mp;

const long long inf = 0x3f3f3f3f;

long long SZ(long long n){
      return to_string(n).size();
}

string getS(long long n){
    if(mp.find(n) != mp.end() && mp[n].size() < SZ(n)){
        return mp[n];
    }
    return to_string(n);
}
int main() {
    long long n;
    cin>>n;

    long long ans = 100000;

    long long to = min(ans,n);

    for(int i = 2 ; i <= to; ++i){
        long long x = i;
        for(int j = 2; ; ++j){
            x *= i;
            if(x > n)break;
            string s = to_string(i) + "^" + to_string(j);
            if(mp.find(x) == mp.end() || mp[x].size() > s.size()){
                mp[x] = s;
            }
        }
    }
    string sol = getS(n);
    string ss= "";
    for(auto a : mp){
      long long x = a.first;
      long long y = n / x;
      long long z = n % x;

      string s = getS(x);
      ss = getS(x);
      if(y > 1){s += "*"+getS(y);ss += "*" + getS(y);}
      if(z > 0){s += "+"+getS(z);ss += "*" + getS(z);}
      //sol = s;
      if(s.size() < sol.size())sol = s;
      //cout<<s<<endl;
    }
    cout<<sol<<endl;
    //cout<<ss<<endl;

}


#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(vr) vr.begin(),vr.end()
const ll inf=1e10,mpow=33,N=1e5,M=1e3;
vector<int> prime;
int nt[N+10];

void sieve()
{
    for (int i=2;i<=N;i++)
        if (!nt[i])
        {
            prime.pb(i);
            for (int j=i*2;j<=N;j+=i) nt[j]=1;
        }
}

string tostring(ll x)
{
    string res;
    while (x)
    {
        char ch=(char)(x%10+48);
        res=ch+res;
        x/=10;
    }
    return res;
}

ll power(ll x,int h)
{
    ll res=1;
    for (;h;h>>=1)
    {
        if (h&1)
        {
            if (res>inf/x) return inf;
            res=res*x;
        }
        if (h==1) return res;
        if (x>inf/x) return inf;
        x=x*x;
    }
    return res;
}

int cb(ll x,int h)
{
    int l=2,r=N;
    while (l<=r)
    {
        int mid=(l+r)/2;
        ll tmp=power(mid,h);
        if (tmp>x) r=mid-1;
        else if (tmp<x) l=mid+1;
        else return mid;
    }
    return -1;
}

string best_rep1(ll x)
{
    string res=tostring(x);
    for (int i=2;i<=mpow;i++)
    {
        int tmp=cb(x,i);
        if (tmp==-1) continue;
        string can=tostring(tmp)+"^"+tostring(i);
        if (can.length()<res.length()) res=can;
    }
    return res;
}

map<int,string> in_num3,in_num4;

vector<ll> divi(ll x)
{
    vector<ll> res;
    res.pb(1);
    for (int p : prime)
        if (x%p==0)
        {
            ll bonus=1;
            while (x%p==0)
            {
                x/=p;
                bonus*=p;
                for (ll k : res)
                {
                    if (k%p==0) break;
                    res.pb(k*bonus);
                }
            }
        }
    if (x>1)
    {
        for (ll k : res)
        {
            if (k%x==0) break;
            res.pb(k*x);
        }
    }
    return res;
}

string best_rep2(ll x,int mlen)
{
    string res=best_rep1(x);
    vector<ll> divisor=divi(x);
    sort(all(divisor));
    for (ll k : divisor)
    {
        if (x/k<k) break;
        string can=best_rep1(k)+"*"+best_rep1(x/k);
        if (can.length()<res.length()) res=can;
    }
    if (mlen==9)
    {
        for (int i=2;i<=9;i++)
            for (int j=2;j<=9;j++)
                for (int t=2;t<=9;t++)
                {
                    ll tmp=power(i,j)*t;
                    string st=in_num3[x/tmp];
                    if (x%tmp==0 && st!="")
                    {
                        string can=tostring(i)+"^"+tostring(j)+"*"+st+"*"+tostring(t);
                        if (can.length()<res.length()) res=can;
                    }
                }
    }
    return res;
}

string solve(ll n)
{
    if (n==1e10) return "10^10";
    for (int i=2;i<=9;i++)
        for (int j=2;j<=9;j++) in_num3[power(i,j)]=tostring(i)+"^"+tostring(j);
    string res=best_rep2(n,9);
    ll R=n,L=max((ll)1,n-M+1);
    for (ll i=L;i<R;i++)
    {
        string can=tostring(n-i)+"+";
        can+=best_rep2(i,9-(int)can.length());
        if (can.length()<res.length()) res=can;
    }
    for (int i=2;i<=99;i++)
        for (int j=2;j<=mpow;j++)
        {
            ll tmp=power(i,j);
            if (tmp>=n) continue;
            in_num4[tmp]=tostring(i)+"^"+tostring(j);
            string can=tostring(i)+"^"+tostring(j)+"+"+tostring(n-tmp);
            if (can.length()<res.length()) res=can;
        }
    for (int i=2;i<=99;i++)
        for (int j=2;j<=mpow;j++)
        {
            ll tmp=power(i,j);
            if (tmp>=n) continue;
            string st=in_num4[n-tmp];
            if (st!="")
            {
                string can=tostring(i)+"^"+tostring(j)+"+"+st;
                if (can.length()<res.length()) res=can;
            }
        }
    for (int i=2;i<=9;i++)
        for (int j=2;j<=9;j++)
        {
            for (int t=2;t<=9;t++)
            {
                ll tmp=power(i,j)+t;
                string st=in_num3[n-tmp];
                if (st!="")
                {
                    string can=tostring(i)+"^"+tostring(j)+"+"+st+"+"+tostring(t);
                    if (can.length()<res.length()) res=can;
                }
            }
            ll tmp=power(i,j);
            if (tmp>=n) continue;
            string can=tostring(i)+"^"+tostring(j)+"+";
            can+=best_rep2(n-tmp,9-can.length());
            if (can.length()<res.length()) res=can;
        }
    return res;
}

int main()
{
    //freopen("ss.inp","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll n;
    cin>>n;
    sieve();
    cout<<solve(n);
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(vr) vr.begin(),vr.end()
const ll inf=1e10,mpow=33,N=1e5,M=1e3;

string tostring(ll x)
{
    string res;
    while (x)
    {
        char ch=(char)(x%10+48);
        res=ch+res;
        x/=10;
    }
    return res;
}

ll power(ll x,int h)
{
    ll res=1;
    for (;h;h>>=1)
    {
        if (h&1)
        {
            if (res>inf/x) return inf;
            res=res*x;
        }
        if (h==1) return res;
        if (x>inf/x) return inf;
        x=x*x;
    }
    return res;
}

int cb(ll x,int h)
{
    int l=2,r=N;
    while (l<=r)
    {
        int mid=(l+r)/2;
        ll tmp=power(mid,h);
        if (tmp>x) r=mid-1;
        else if (tmp<x) l=mid+1;
        else return mid;
    }
    return -1;
}

string best_rep1(ll x)
{
    string res=tostring(x);
    for (int i=2;i<=mpow;i++)
    {
        int tmp=cb(x,i);
        if (tmp==-1) continue;
        string can=tostring(tmp)+"^"+tostring(i);
        if (can.length()<res.length()) res=can;
    }
    return res;
}

map<int,string> in_num3;

string best_rep2(ll x,vector<ll> &divisor,int mlen)
{
    string res=best_rep1(x);
    sort(all(divisor));
    for (ll k : divisor)
    {
        if (x/k<k) break;
        string can=best_rep1(k)+"*"+best_rep1(x/k);
        if (can.length()<res.length()) res=can;
    }
    if (mlen==9)
    {
        for (int i=2;i<=9;i++)
            for (int j=2;j<=9;j++)
                for (int t=2;t<=9;t++)
                {
                    ll tmp=power(i,j)*t;
                    string st=in_num3[x/tmp];
                    if (x%tmp==0 && st!="")
                    {
                        string can=tostring(i)+"^"+tostring(j)+"*"+st+"*"+tostring(t);
                        if (can.length()<res.length()) res=can;
                    }
                }
    }
    return res;
}

vector<ll> divi[M+10];

string solve(ll n)
{
    if (n==1e10) return "10^10";
    for (int i=2;i<=9;i++)
        for (int j=2;j<=9;j++) in_num3[power(i,j)]=tostring(i)+"^"+tostring(j);
    ll R=n,L=max((ll)1,n-M+1);
    for (int i=1;i<=1e5;i++)
        for (ll j=((L-1)/i+1)*i;j<=R;j+=i)
        {
            if (j/i<i) continue;
            divi[j-L+1].pb(i);
            if (j/i!=i) divi[j-L+1].pb(j/i);
        }
    string res=best_rep2(n,divi[R-L+1],9);
    for (ll i=L;i<R;i++)
    {
        string can=tostring(n-i)+"+";
        can+=best_rep2(i,divi[i-L+1],9-(int)can.length());
        if (can.length()<res.length()) res=can;
    }
    for (int i=2;i<=99;i++)
        for (int j=2;j<=mpow;j++)
        {
            ll tmp=power(i,j);
            if (tmp>=n) continue;
            string can=tostring(i)+"^"+tostring(j)+"+"+tostring(n-tmp);
            if (can.length()<res.length()) res=can;
        }
    for (int i=2;i<=9;i++)
        for (int j=2;j<=9;j++)
            for (int t=2;t<=9;t++)
            {
                ll tmp=power(i,j)+t;
                string st=in_num3[n-tmp];
                if (st!="")
                {
                    string can=tostring(i)+"^"+tostring(j)+"+"+st+"+"+tostring(t);
                    if (can.length()<res.length()) res=can;
                }
            }
    return res;
}

int main()
{
    //freopen("ss.inp","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll n;
    cin>>n;
    cout<<solve(n);
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(vr) vr.begin(),vr.end()
const ll inf=1e10,mpow=33,N=1e5,M=1e3;
vector<int> prime;
int nt[N+10];

void sieve()
{
    for (int i=2;i<=N;i++)
        if (!nt[i])
        {
            prime.pb(i);
            for (int j=i*2;j<=N;j+=i) nt[j]=1;
        }
}

string tostring(ll x)
{
    string res;
    while (x)
    {
        char ch=(char)(x%10+48);
        res=ch+res;
        x/=10;
    }
    return res;
}

ll power(ll x,int h)
{
    ll res=1;
    for (;h;h>>=1)
    {
        if (h&1)
        {
            if (res>inf/x) return inf;
            res=res*x;
        }
        if (h==1) return res;
        if (x>inf/x) return inf;
        x=x*x;
    }
    return res;
}

int cb(ll x,int h)
{
    int l=2,r=N;
    while (l<=r)
    {
        int mid=(l+r)/2;
        ll tmp=power(mid,h);
        if (tmp>x) r=mid-1;
        else if (tmp<x) l=mid+1;
        else return mid;
    }
    return -1;
}

string best_rep1(ll x)
{
    string res=tostring(x);
    for (int i=2;i<=mpow;i++)
    {
        int tmp=cb(x,i);
        if (tmp==-1) continue;
        string can=tostring(tmp)+"^"+tostring(i);
        if (can.length()<res.length()) res=can;
    }
    return res;
}

map<int,string> in_num3,in_num4;

vector<ll> divi(ll x)
{
    vector<ll> res;
    res.pb(1);
    for (int p : prime)
        if (x%p==0)
        {
            ll bonus=1;
            while (x%p==0)
            {
                x/=p;
                bonus*=p;
                for (ll k : res)
                {
                    if (k%p==0) break;
                    res.pb(k*bonus);
                }
            }
        }
    if (x>1)
    {
        for (ll k : res)
        {
            if (k%x==0) break;
            res.pb(k*x);
        }
    }
    return res;
}

string best_rep2(ll x,int mlen)
{
    string res=best_rep1(x);
    vector<ll> divisor=divi(x);
    sort(all(divisor));
    for (ll k : divisor)
    {
        if (x/k<k) break;
        string can=best_rep1(k)+"*"+best_rep1(x/k);
        if (can.length()<res.length()) res=can;
    }
    if (mlen==9)
    {
        for (int i=2;i<=9;i++)
            for (int j=2;j<=9;j++)
                for (int t=2;t<=9;t++)
                {
                    ll tmp=power(i,j)*t;
                    string st=in_num3[x/tmp];
                    if (x%tmp==0 && st!="")
                    {
                        string can=tostring(i)+"^"+tostring(j)+"*"+st+"*"+tostring(t);
                        if (can.length()<res.length()) res=can;
                    }
                }
    }
    return res;
}

string solve(ll n)
{
    if (n==1e10) return "10^10";
    for (int i=2;i<=9;i++)
        for (int j=2;j<=9;j++) in_num3[power(i,j)]=tostring(i)+"^"+tostring(j);
    string res=best_rep2(n,9);
    ll R=n,L=max((ll)1,n-M+1);
    for (ll i=L;i<R;i++)
    {
        string can=tostring(n-i)+"+";
        can+=best_rep2(i,9-(int)can.length());
        if (can.length()<res.length()) res=can;
    }
    for (int i=2;i<=99;i++)
        for (int j=2;j<=mpow;j++)
        {
            ll tmp=power(i,j);
            if (tmp>=n) continue;
            in_num4[tmp]=tostring(i)+"^"+tostring(j);
            string can=tostring(i)+"^"+tostring(j)+"+"+tostring(n-tmp);
            if (can.length()<res.length()) res=can;
        }
    for (int i=2;i<=99;i++)
        for (int j=2;j<=mpow;j++)
        {
            ll tmp=power(i,j);
            if (tmp>=n) continue;
            string st=in_num4[n-tmp];
            if (st!="")
            {
                string can=tostring(i)+"^"+tostring(j)+"+"+st;
                if (can.length()<res.length()) res=can;
            }
        }
    for (int i=2;i<=9;i++)
        for (int j=2;j<=9;j++)
        {
            for (int t=2;t<=9;t++)
            {
                ll tmp=power(i,j)+t;
                string st=in_num3[n-tmp];
                if (st!="")
                {
                    string can=tostring(i)+"^"+tostring(j)+"+"+st+"+"+tostring(t);
                    if (can.length()<res.length()) res=can;
                }
            }
            ll tmp=power(i,j);
            string can=tostring(i)+"^"+tostring(j)+"+";
            can+=best_rep2(n-tmp,9-can.length());
            if (can.length()<res.length()) res=can;
        }
    return res;
}

int main()
{
    //freopen("ss.inp","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll n;
    cin>>n;
    sieve();
    cout<<solve(n);
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(vr) vr.begin(),vr.end()
const ll inf=1e10,mpow=33,N=1e5,M=1e3;
vector<int> prime;
int nt[N+10];

void sieve()
{
    for (int i=2;i<=N;i++)
        if (!nt[i])
        {
            prime.pb(i);
            for (int j=i*2;j<=N;j+=i) nt[j]=1;
        }
}

string tostring(ll x)
{
    string res;
    while (x)
    {
        char ch=(char)(x%10+48);
        res=ch+res;
        x/=10;
    }
    return res;
}

ll power(ll x,int h)
{
    ll res=1;
    for (;h;h>>=1)
    {
        if (h&1)
        {
            if (res>inf/x) return inf;
            res=res*x;
        }
        if (h==1) return res;
        if (x>inf/x) return inf;
        x=x*x;
    }
    return res;
}

int cb(ll x,int h)
{
    int l=2,r=N;
    while (l<=r)
    {
        int mid=(l+r)/2;
        ll tmp=power(mid,h);
        if (tmp>x) r=mid-1;
        else if (tmp<x) l=mid+1;
        else return mid;
    }
    return -1;
}

string best_rep1(ll x)
{
    string res=tostring(x);
    for (int i=2;i<=mpow;i++)
    {
        int tmp=cb(x,i);
        if (tmp==-1) continue;
        string can=tostring(tmp)+"^"+tostring(i);
        if (can.length()<res.length()) res=can;
    }
    return res;
}

map<ll,string> in_num3,in_num4;

vector<ll> divi(ll x)
{
    vector<ll> res;
    res.pb(1);
    for (int p : prime)
        if (x%p==0)
        {
            ll bonus=1;
            while (x%p==0)
            {
                x/=p;
                bonus*=p;
                for (ll k : res)
                {
                    if (k%p==0) break;
                    res.pb(k*bonus);
                }
            }
        }
    if (x>1)
    {
        for (ll k : res)
        {
            if (k%x==0) break;
            res.pb(k*x);
        }
    }
    return res;
}

string best_rep2(ll x,int mlen)
{
    string res=best_rep1(x);
    vector<ll> divisor=divi(x);
    sort(all(divisor));
    for (ll k : divisor)
    {
        if (x/k<k) break;
        string can=best_rep1(k)+"*"+best_rep1(x/k);
        if (can.length()<res.length()) res=can;
    }
    if (mlen==9)
    {
        for (int i=2;i<=9;i++)
            for (int j=2;j<=9;j++)
                for (int t=2;t<=9;t++)
                {
                    ll tmp=power(i,j)*t;
                    string st=in_num3[x/tmp];
                    if (x%tmp==0 && st!="")
                    {
                        string can=tostring(i)+"^"+tostring(j)+"*"+st+"*"+tostring(t);
                        if (can.length()<res.length()) res=can;
                    }
                }
    }
    return res;
}

string solve(ll n)
{
    if (n==1e10) return "10^10";
    for (int i=2;i<=9;i++)
        for (int j=2;j<=9;j++) in_num3[power(i,j)]=tostring(i)+"^"+tostring(j);
    string res=best_rep2(n,9);
    ll R=n,L=max((ll)1,n-M+1);
    for (ll i=L;i<R;i++)
    {
        string can=tostring(n-i)+"+";
        can+=best_rep2(i,9-(int)can.length());
        if (can.length()<res.length()) res=can;
    }
    for (int i=2;i<=99;i++)
        for (int j=2;j<=mpow;j++)
        {
            ll tmp=power(i,j);
            if (tmp>=n) continue;
            in_num4[tmp]=tostring(i)+"^"+tostring(j);
            string can=tostring(i)+"^"+tostring(j)+"+"+tostring(n-tmp);
            if (can.length()<res.length()) res=can;
        }
    for (int i=2;i<=99;i++)
        for (int j=2;j<=mpow;j++)
        {
            ll tmp=power(i,j);
            if (tmp>=n) continue;
            string st=in_num4[n-tmp];
            if (st!="")
            {
                string can=tostring(i)+"^"+tostring(j)+"+"+st;
                if (can.length()<res.length()) res=can;
            }
        }
    for (int i=2;i<=9;i++)
        for (int j=2;j<=9;j++)
        {
            for (int t=2;t<=9;t++)
            {
                ll tmp=power(i,j)+t;
                string st=in_num3[n-tmp];
                if (st!="")
                {
                    string can=tostring(i)+"^"+tostring(j)+"+"+st+"+"+tostring(t);
                    if (can.length()<res.length()) res=can;
                }
            }
            ll tmp=power(i,j);
            if (tmp>=n) continue;
            string can=tostring(i)+"^"+tostring(j)+"+";
            can+=best_rep2(n-tmp,9-can.length());
            if (can.length()<res.length()) res=can;
        }
    return res;
}

int main()
{
    //freopen("ss.inp","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll n;
    cin>>n;
    sieve();
    cout<<solve(n);
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(vr) vr.begin(),vr.end()
const ll inf=1e10,mpow=33,N=1e5,M=1e3;

string tostring(ll x)
{
    string res;
    while (x)
    {
        char ch=(char)(x%10+48);
        res=ch+res;
        x/=10;
    }
    return res;
}

ll power(ll x,int h)
{
    ll res=1;
    for (;h;h>>=1)
    {
        if (h&1)
        {
            if (res>inf/x) return inf;
            res=res*x;
        }
        if (h==1) return res;
        if (x>inf/x) return inf;
        x=x*x;
    }
    return res;
}

int cb(ll x,int h)
{
    int l=2,r=N;
    while (l<=r)
    {
        int mid=(l+r)/2;
        ll tmp=power(mid,h);
        if (tmp>x) r=mid-1;
        else if (tmp<x) l=mid+1;
        else return mid;
    }
    return -1;
}

string best_rep1(ll x)
{
    string res=tostring(x);
    for (int i=2;i<=mpow;i++)
    {
        int tmp=cb(x,i);
        if (tmp==-1) continue;
        string can=tostring(tmp)+"^"+tostring(i);
        if (can.length()<res.length()) res=can;
    }
    return res;
}

map<int,string> in_num3;

string best_rep2(ll x,vector<ll> &divisor,int mlen)
{
    string res=best_rep1(x);
    sort(all(divisor));
    for (ll k : divisor)
    {
        if (x/k<k) break;
        string can=best_rep1(k)+"*"+best_rep1(x/k);
        if (can.length()<res.length()) res=can;
    }
    if (mlen==9)
    {
        for (int i=2;i<=9;i++)
            for (int j=2;j<=9;j++)
                for (int t=2;t<=9;t++)
                {
                    ll tmp=pow(i,j)*t;
                    string st=in_num3[x/tmp];
                    if (x%tmp==0 && st!="")
                    {
                        string can=tostring(i)+"^"+tostring(j)+"*"+st+"*"+tostring(t);
                        if (can.length()<res.length()) res=can;
                    }
                }
    }
    return res;
}

vector<ll> divi[M+10];

string solve(ll n)
{
    if (n==1e10) return "10^10";
    for (int i=2;i<=9;i++)
        for (int j=2;j<=9;j++) in_num3[pow(i,j)]=tostring(i)+"^"+tostring(j);
    ll R=n,L=max((ll)1,n-M+1);
    for (int i=1;i<=1e5;i++)
        for (ll j=((L-1)/i+1)*i;j<=R;j+=i)
        {
            if (j/i<i) continue;
            divi[j-L+1].pb(i);
            if (j/i!=i) divi[j-L+1].pb(j/i);
        }
    string res=best_rep2(n,divi[R-L+1],9);
    for (ll i=L;i<R;i++)
    {
        string can=tostring(n-i)+"+";
        can+=best_rep2(i,divi[i-L+1],9-(int)can.length());
        if (can.length()<res.length()) res=can;
    }
    for (int i=2;i<=99;i++)
        for (int j=2;j<=mpow;j++)
        {
            int tmp=pow(i,j);
            if (tmp>=n) continue;
            string can=tostring(i)+"^"+tostring(j)+"+"+tostring(n-tmp);
            if (can.length()<res.length()) res=can;
        }
    for (int i=2;i<=9;i++)
        for (int j=2;j<=9;j++)
            for (int t=2;t<=9;t++)
            {
                ll tmp=pow(i,j)+t;
                string st=in_num3[n-tmp];
                if (st!="")
                {
                    string can=tostring(i)+"^"+tostring(j)+"+"+st+"+"+tostring(t);
                    if (can.length()<res.length()) res=can;
                }
            }
    return res;
}

int main()
{
    //freopen("ss.inp","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll n;
    cin>>n;
    cout<<solve(n);
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(vr) vr.begin(),vr.end()
const ll inf=1e10,mpow=33,N=1e5,M=1e3;

string tostring(ll x)
{
    string res;
    while (x)
    {
        char ch=(char)(x%10+48);
        res=ch+res;
        x/=10;
    }
    return res;
}

ll power(ll x,int h)
{
    ll res=1;
    for (;h;h>>=1)
    {
        if (h&1)
        {
            if (res>inf/x) return inf;
            res=res*x;
        }
        if (h==1) return res;
        if (x>inf/x) return inf;
        x=x*x;
    }
    return res;
}

int cb(ll x,int h)
{
    int l=2,r=N;
    while (l<=r)
    {
        int mid=(l+r)/2;
        ll tmp=power(mid,h);
        if (tmp>x) r=mid-1;
        else if (tmp<x) l=mid+1;
        else return mid;
    }
    return -1;
}

string best_rep1(ll x)
{
    string res=tostring(x);
    for (int i=2;i<=mpow;i++)
    {
        int tmp=cb(x,i);
        if (tmp==-1) continue;
        string can=tostring(tmp)+"^"+tostring(i);
        if (can.length()<res.length()) res=can;
    }
    return res;
}

map<int,string> in_num3;

string best_rep2(ll x,vector<ll> &divisor,int mlen)
{
    string res=best_rep1(x);
    sort(all(divisor));
    for (ll k : divisor)
    {
        if (x/k<k) break;
        string can=best_rep1(k)+"*"+best_rep1(x/k);
        if (can.length()<res.length()) res=can;
    }
    if (mlen==9)
    {
        for (int i=2;i<=9;i++)
            for (int j=2;j<=9;j++)
                for (int t=2;t<=9;t++)
                {
                    ll tmp=pow(i,j)*t;
                    string st=in_num3[x/tmp];
                    if (x%tmp==0 && st!="")
                    {
                        string can=tostring(i)+"^"+tostring(j)+"*"+st+"*"+tostring(t);
                        if (can.length()<res.length()) res=can;
                    }
                }
    }
    return res;
}

vector<ll> divi[M+10];

string solve(ll n)
{
    if (n==1e10) return "10^10";
    for (int i=2;i<=9;i++)
        for (int j=2;j<=9;j++) in_num3[pow(i,j)]=tostring(i)+"^"+tostring(j);
    ll R=n,L=max((ll)1,n-M+1);
    for (int i=1;i<=1e5;i++)
        for (ll j=((L-1)/i+1)*i;j<=R;j+=i)
        {
            if (j/i<i) continue;
            divi[j-L+1].pb(i);
            if (j/i!=i) divi[j-L+1].pb(j/i);
        }
    string res=best_rep2(n,divi[R-L+1],9);
    for (ll i=L;i<R;i++)
    {
        string can=tostring(n-i)+"+";
        can+=best_rep2(i,divi[i-L+1],9-(int)can.length());
        if (can.length()<res.length()) res=can;
    }
    for (int i=2;i<=99;i++)
        for (int j=2;j<=mpow;j++)
        {
            ll tmp=pow(i,j);
            if (tmp>=n) continue;
            string can=tostring(i)+"^"+tostring(j)+"+"+tostring(n-tmp);
            if (can.length()<res.length()) res=can;
        }
    for (int i=2;i<=9;i++)
        for (int j=2;j<=9;j++)
            for (int t=2;t<=9;t++)
            {
                ll tmp=pow(i,j)+t;
                string st=in_num3[n-tmp];
                if (st!="")
                {
                    string can=tostring(i)+"^"+tostring(j)+"+"+st+"+"+tostring(t);
                    if (can.length()<res.length()) res=can;
                }
            }
    return res;
}

int main()
{
    //freopen("ss.inp","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll n;
    cin>>n;
    cout<<solve(n);
    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 (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) {
			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) {
			if (s.size() >= ans) return;
			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.first >= ans) continue;
		calc(p.first, p.second);
		if (p.first + 2 >= ans) continue;
		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);

	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 (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) {
			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) {
			if (s.size() >= ans) return;
			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);
			}
		};

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

	OUT(anss)BR;

	return 0;
}