# 3365. 打字员吉吉木

from functools import lru_cache

s = input()

@lru_cache(None)
def dfs(idx: int, cp: str):
if idx == len(s):
return 0
a_tm = dfs(idx + 1, cp) + 1
if idx + 1 == len(s) or s[idx:idx + 2] not in s[:idx]:
return a_tm
p_tm = dfs(idx + len(cp), cp) + 1 if s[idx:idx + len(cp)] == cp else 10032
ed = idx + 2
while ed != len(s) and s[idx:ed + 1] in s[:idx]:
ed += 1
cp_tm = min(dfs(i, s[idx:i]) for i in range(idx + 2, ed + 1)) + 2
return min(a_tm, p_tm, cp_tm)

print(dfs(0, '_'))


struct state{
long num;
string copy;
state(int num, string copy){
this->num = num;
this->copy = copy;
}
state(){
this->num = 0;
this->copy = “”;
}
};
int helper(string s){
if (s.length() <= 3)
return s.length();
int n = s.size();
vector dp(n);
dp[0].num = 1;
dp[1].num = 2;
//dp[i]表示0-i打印出来需要的最短时间
for (int i = 2; i <n; i++){
//遍历前面
dp[i].num = dp[i - 1].num + 1; //默认直接输出一个字符
//j表示从i开始往前数j个是通过粘贴来的
for (int j = 2; j <= (i + 1) / 2; j++){
if (dp[i - j].copy == s.substr(i - j + 1, j)){
if (dp[i].num >= dp[i - j].num + 1){
dp[i].num = dp[i - j].num + 1;
dp[i].copy = dp[i - j].copy;
}
}

        if (match(s.substr(0, i - j + 1), s.substr(i - j + 1, j))){
if (dp[i].num >= dp[i - j].num + 2){
dp[i].num = dp[i - j].num + 2;
dp[i].copy = s.substr(i - j + 1, j);
}
}

}
}
return dp[n - 1].num;


}