#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <list>
#include <ctime>
#include <math.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>
 
using namespace std;
 
void ASS(bool b)
{
	if (!b)
	{
		++*(int*)0;
	}
}

#define FOR(i, n) for (int i = 0; i < (int)n; ++i)
 
typedef long long LL;
typedef vector<int> vi;

bool isCyclic(const char* s, int n, int len)
{
	for (int i = len; i < n; ++i)
		if (s[i] != s[i - len])
			return false;
	return true;
}

string Str(int x)
{
	stringstream ss;
	ss << x;
	return ss.str();
}

const int N = 107;

char s[N];
string d[N][N];

/*
string D(int L, int R)
{
	if (L + 1 == R)
		return string(s + L, s + R);
	if (d[L][R].size())
		return d[L][R];
	string res = string(s + L, s + R);
	int n = R - L;
	for (int i = 1; i <= n; i++)
		if (n / i >= 2 && n % i == 0 && isCyclic(s + L, n, i))
		{
			string zip = Str(n / i) + "(" + D(L, L + i) + ")";
			if (res.size() > zip.size())
				res = zip;
		}
	for (int i = L + 1; i < R; i++) {
		string zip = D(L, i) + D(i, R);
		if (res.size() > zip.size())
			res = zip;
	}
	d[L][R] = res;
	return res;
}
*/

void DPnonRec(int L, int R)
{
	if (L + 1 == R)
	{
		d[L][R] = string(s + L, s + R);
		return;
	}

	string res = string(s + L, s + R);
	int n = R - L;
	for (int i = 1; i <= n; i++)
		if (n / i >= 2 && n % i == 0 && isCyclic(s + L, n, i))
		{
			string zip = Str(n / i) + "(" + d[L][L + i] + ")";
			if (res.size() > zip.size())
				res = zip;
		}
	for (int i = L + 1; i < R; i++) {
		string zip = d[L][i] + d[i][R];
		if (res.size() > zip.size())
			res = zip;
	}
	d[L][R] = res;
}


string Solve()
{
	int n = (int)strlen(s);
	//return D(0, n);
	for (int len = 1; len <= n; ++len)
		for (int i = 0; i + len <= n; ++i)
			DPnonRec(i, i + len);
	return d[0][n];
}

int main()
{
	cin >> s;
	cout << Solve() << "\n";

    return 0;
}