#include <iostream>
#include <string>
#include <limits>
#include <cstring>
using namespace std;
// determine how many times the prefix of specific length is repeated in the input
int repetitions(string const & input, int prefix_length)
{
int i = 1;
while (
(i + 1) * prefix_length <= input.size() &&
memcmp(input.data(), input.data() + i * prefix_length, prefix_length) == 0
)
{
++i;
}
return i;
}
// recursively compress input and return compressed string
string compress(string const & input)
{
// recursion termination
if (input.empty())
return string();
string best;
int best_length = numeric_limits<int>::max();
// try various prefix lengths
for (int prefix_length = 1; prefix_length <= input.length(); ++prefix_length)
{
const auto max_count = repetitions(input, prefix_length);
// try various number of repetitions up to the maximum possible
for (int count = 1; count <= max_count; ++count)
{
// the candidate is compressed prefix and the rest of input compressed recursively
const auto current =
to_string(count) + input.substr(0, prefix_length) + // compressed prefix
compress(input.substr(prefix_length * count)); // the rest of input compressed recursively
// store candidate if it is better than the currently best
if (current.length() < best_length)
{
best = current;
best_length = current.length();
}
}
}
return best;
}
int main()
{
string input;
cin >> input;
cout << compress(input);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8bGltaXRzPgojaW5jbHVkZSA8Y3N0cmluZz4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCi8vIGRldGVybWluZSBob3cgbWFueSB0aW1lcyB0aGUgcHJlZml4IG9mIHNwZWNpZmljIGxlbmd0aCBpcyByZXBlYXRlZCBpbiB0aGUgaW5wdXQKaW50IHJlcGV0aXRpb25zKHN0cmluZyBjb25zdCAmIGlucHV0LCBpbnQgcHJlZml4X2xlbmd0aCkKewoJaW50IGkgPSAxOwoJd2hpbGUgKAoJCShpICsgMSkgKiBwcmVmaXhfbGVuZ3RoIDw9IGlucHV0LnNpemUoKSAmJiAKCQltZW1jbXAoaW5wdXQuZGF0YSgpLCBpbnB1dC5kYXRhKCkgKyBpICogcHJlZml4X2xlbmd0aCwgcHJlZml4X2xlbmd0aCkgPT0gMAoJCSkKCXsKCQkrK2k7Cgl9CgkKCXJldHVybiBpOwp9CgovLyByZWN1cnNpdmVseSBjb21wcmVzcyBpbnB1dCBhbmQgcmV0dXJuIGNvbXByZXNzZWQgc3RyaW5nCnN0cmluZyBjb21wcmVzcyhzdHJpbmcgY29uc3QgJiBpbnB1dCkKewoJLy8gcmVjdXJzaW9uIHRlcm1pbmF0aW9uCglpZiAoaW5wdXQuZW1wdHkoKSkKCQlyZXR1cm4gc3RyaW5nKCk7CgoJc3RyaW5nIGJlc3Q7CglpbnQgYmVzdF9sZW5ndGggPSBudW1lcmljX2xpbWl0czxpbnQ+OjptYXgoKTsKCgkvLyB0cnkgdmFyaW91cyBwcmVmaXggbGVuZ3RocwoJZm9yIChpbnQgcHJlZml4X2xlbmd0aCA9IDE7IHByZWZpeF9sZW5ndGggPD0gaW5wdXQubGVuZ3RoKCk7ICsrcHJlZml4X2xlbmd0aCkKCXsKCQljb25zdCBhdXRvIG1heF9jb3VudCA9IHJlcGV0aXRpb25zKGlucHV0LCBwcmVmaXhfbGVuZ3RoKTsKCQkKCQkvLyB0cnkgdmFyaW91cyBudW1iZXIgb2YgcmVwZXRpdGlvbnMgdXAgdG8gdGhlIG1heGltdW0gcG9zc2libGUKCQlmb3IgKGludCBjb3VudCA9IDE7IGNvdW50IDw9IG1heF9jb3VudDsgKytjb3VudCkKCQl7CgkJCS8vIHRoZSBjYW5kaWRhdGUgaXMgY29tcHJlc3NlZCBwcmVmaXggYW5kIHRoZSByZXN0IG9mIGlucHV0IGNvbXByZXNzZWQgcmVjdXJzaXZlbHkKCQkJY29uc3QgYXV0byBjdXJyZW50ID0gCgkJCQl0b19zdHJpbmcoY291bnQpICsgaW5wdXQuc3Vic3RyKDAsIHByZWZpeF9sZW5ndGgpICsgLy8gY29tcHJlc3NlZCBwcmVmaXgKCQkJCWNvbXByZXNzKGlucHV0LnN1YnN0cihwcmVmaXhfbGVuZ3RoICogY291bnQpKTsgLy8gdGhlIHJlc3Qgb2YgaW5wdXQgY29tcHJlc3NlZCByZWN1cnNpdmVseQoJCQkKCQkJLy8gc3RvcmUgY2FuZGlkYXRlIGlmIGl0IGlzIGJldHRlciB0aGFuIHRoZSBjdXJyZW50bHkgYmVzdAoJCQlpZiAoY3VycmVudC5sZW5ndGgoKSA8IGJlc3RfbGVuZ3RoKQoJCQl7CgkJCQliZXN0ID0gY3VycmVudDsKCQkJCWJlc3RfbGVuZ3RoID0gY3VycmVudC5sZW5ndGgoKTsKCQkJfQoJCX0KCX0KCglyZXR1cm4gYmVzdDsKfQoKaW50IG1haW4oKSAKewoJc3RyaW5nIGlucHV0OwoJY2luID4+IGlucHV0OwoJY291dCA8PCBjb21wcmVzcyhpbnB1dCk7CglyZXR1cm4gMDsKfQ==