#include <bits/stdc++.h>
using namespace std;
#define FastIO ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define ll long long
#define ull unsigned long long
#define ld long double
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define sz(v) ((int)(v).size())
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define clr(v, d) memset(v, d, sizeof(v))
#define forn(i, e) for (int i = 0; i < e; i++)
#define fors(i, s, e) for (int i = s; i < e; i++)
#define rforn(i, s) for (int i = s; i >= 0; i--)
#define rfors(i, s, e) for (int i = s; i >= e; i--)
#define msb(x) (63 - __builtin_clzll((unsigned long long)(x)))
#define lsb(x) (__builtin_ctzll((unsigned long long)(x)))
#define bit_count(x) (__builtin_popcountll((unsigned long long)(x)))
#ifndef ONLINE_JUDGE
#define debug(x) cerr << #x << " = " << (x) << '\n';
#else
#define debug(x)
#endif
typedef vector<int> vi;
typedef vector<double> vd;
typedef vector< vi > vvi;
typedef vector< vd > vvd;
typedef vector<string> vs;
const int INF = 1e9 + 7;
const ll LINF = 1e18 + 7;
const double EPS = 1e-9;
const int MAXN = 8005;
const int LOG = 20;
// #define int ll
const int dx[] = {-1, 1, 0, 0, -1, -1, 1, 1};
const int dy[] = {0, 0, -1, 1, -1, 1, -1, 1};
const ll MOD1 = 1e9 + 7;
const ll MOD2 = 998244353;
ll BASE1 = 31, BASE2 = 37;
ll pw1[MAXN], pw2[MAXN], inv1[MAXN], inv2[MAXN];
int spf[MAXN];
ll fastPow(ll x, ll y, ll m) {
x %= m;
ll res = 1;
while (y > 0) {
if (y & 1) res = (res * x) % m;
x = (x * x) % m;
y >>= 1;
}
return res;
}
ll modInv(ll x, ll m) {
return fastPow(x, m - 2, m);
}
void init_hash() {
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
BASE1 = uniform_int_distribution<ll>(300, 1000)(rng) | 1;
do {
BASE2 = uniform_int_distribution<ll>(300, 1000)(rng) | 1;
} while (BASE1 == BASE2);
pw1[0] = pw2[0] = inv1[0] = inv2[0] = 1;
ll inv_b1 = modInv(BASE1, MOD1);
ll inv_b2 = modInv(BASE2, MOD2);
for (int i = 1; i < MAXN; i++) {
pw1[i] = (pw1[i - 1] * BASE1) % MOD1;
pw2[i] = (pw2[i - 1] * BASE2) % MOD2;
inv1[i] = (inv1[i - 1] * inv_b1) % MOD1;
inv2[i] = (inv2[i - 1] * inv_b2) % MOD2;
}
}
struct StringHash {
int n;
string s;
vector<pair<ll,ll>> pref, rev_pref;
StringHash(const string &_s) : s(_s), n(_s.size()) {
pref.resize(n);
rev_pref.resize(n);
for (int i = 0; i < n; i++) {
ll val1 = s[i] - 'a' + 1;
ll val2 = s[n - 1 - i] - 'a' + 1;
if (i == 0) {
pref[i] = {val1, val1};
rev_pref[i] = {val2, val2};
} else {
pref[i].first = (pref[i - 1].first * BASE1 + val1) % MOD1;
pref[i].second = (pref[i - 1].second * BASE2 + val1) % MOD2;
rev_pref[i].first = (rev_pref[i - 1].first * BASE1 + val2) % MOD1;
rev_pref[i].second = (rev_pref[i - 1].second * BASE2 + val2) % MOD2;
}
}
}
pair<ll,ll> get_hash(int l, int r) {
if (l > r) return {0, 0};
if (l == 0) return pref[r];
int len = r - l + 1;
ll h1 = (pref[r].first - (pref[l - 1].first * pw1[len]) % MOD1 + MOD1) % MOD1;
ll h2 = (pref[r].second - (pref[l - 1].second * pw2[len]) % MOD2 + MOD2) % MOD2;
return {h1, h2};
}
pair<ll,ll> get_rev_hash(int l, int r) {
if (l > r) return {0, 0};
int rl = n - 1 - r;
int rr = n - 1 - l;
if (rl == 0) return rev_pref[rr];
int len = rr - rl + 1;
ll h1 = (rev_pref[rr].first - (rev_pref[rl - 1].first * pw1[len]) % MOD1 + MOD1) % MOD1;
ll h2 = (rev_pref[rr].second - (rev_pref[rl - 1].second * pw2[len]) % MOD2 + MOD2) % MOD2;
return {h1, h2};
}
bool is_palindrome(int l, int r) {
return get_hash(l, r) == get_rev_hash(l, r);
}
};
int get_digits(int x) {
if (x < 10) return 1;
if (x < 100) return 2;
if (x < 1000) return 3;
if (x < 10000) return 4;
return 5;
}
void solve() {
string s; cin >> s;
int n = s.size();
StringHash h(s);
for (int i = 2; i <= n; i++)
if (!spf[i])
for (int j = i; j <= n; j += i)
if (!spf[j]) spf[j] = i;
vector<int> min_dp(n + 2, INF);
for (int i = n; i >= 1; i--) {
int best = INF;
for (int len = 1;len <= n-i+1;len++) {
int a = i - 1, b = i + len - 2;
int p = len, x = len;
while (x > 1) {
int q = spf[x];
while (x % q == 0) x /= q;
while (p % q == 0) {
int d = p / q;
if (h.get_hash(a, b - d) == h.get_hash(a + d, b)) p = d;
else break;
}
}
int cost = get_digits(len / p) + p;
int rem = (i + len > n) ? 0 : min_dp[i + len];
best = min(best, cost + rem);
}
min_dp[i] = best;
}
cout << min_dp[1] << endl;
}
signed main() {
#ifndef ONLINE_JUDGE
// freopen("feast.in", "rt", stdin);
// freopen("feast.out", "wt", stdout);
#endif
FastIO
int tc = 1;
// cin >> tc;
init_hash();
while (tc--) {
solve();
}
return 0;
}