#include using LL = long long; const int N = 2e6 + 7; char s[N]; int z[N], f[N], set[N], n; std::vector b[N]; void getz() { z[1] = 0; for(int i = 2, p = 1, r = 1; i <= n; ++i) { z[i] = (i < r ? std::min(z[i - p + 1], r - i) : 0); while(s[z[i] + 1] == s[z[i] + i]) ++z[i]; if(i + z[i] > r) { r = i + z[i]; p = i; } } } int find(int x) { return set[x] == x ? x : set[x] = find(set[x]); } void uni(int x, int y) { set[find(x)] = find(y); } void solve() { scanf("%s", s + 1); n = strlen(s + 1); getz(); memset(f, 0x3f, sizeof f); for(int i = 1; i <= n + 1; ++i) { set[i] = i; b[i].clear(); } for(int i = 1; i <= n; ++i) { z[i] = std::min(i - 1, z[i]); if(z[i] <= 1) uni(i, i + 1); else b[z[i]].push_back(i); } f[1] = 1; for(int i = 1; i <= n; ++i) { f[i] = std::min(f[i], f[i - 1] + 1); for(int k = 1, now = find(i); now <= n; ++k, now = find(now + i)) f[i + now - 1] = std::min(f[i + now - 1], f[i] + now - k * (i - 1)); for(int p: b[i]) uni(p, p + 1); } printf("%d\n", f[n]); } int main() { int cases = 1; //scanf("%d", &cases); while(cases--) solve(); return 0; }