import java.lang.Math.max
import java.util.*

const val MOD = 1000000007L
const val INF = Long.MAX_VALUE - 1

fun main(args: Array<String>) {
    val s = readList().first()

    val dp = Array(s.length + 1) {
        return@Array emptyMap<CharSequence, Int>().toMutableMap()
    }

    fun dfs(N: Int, prev: CharSequence): Int {
        if (N == s.length + 1) {
            return 0
        }
        if (dp[N].isNotEmpty()) {
            dp[N].entries.filter { it.component1() != prev }.maxBy { it.component2() }?.component2()?.let {
                return it
            }
        }

        var ret = -1
        var retStrs = emptyList<CharSequence>().toMutableList()
        (s.length + 2).rep(N + 1) {
            if (it - N != prev.length || s.substring(N - 1..it - 2) != prev) {
                val temp = ret
                val x = dfs(it, s.subSequence(N - 1..it - 2)) + 1
                ret = max(ret, x)
                if (x == ret) {
                    if (temp != x) {
                        retStrs.clear()
                    }
                    retStrs.add(s.subSequence(N - 1..it - 2))
                }
            }
        }
        if (ret == -1) return 0
        retStrs.forEach {
            dp[N][prev] = ret
        }
        return ret
    }


    val ans = dfs(1, "")
    println(ans)
}

fun readList() = readLine()!!.split(' ')


inline fun Int.rep(start: Int = 0, shiftLast: Boolean = false, body: (Int) -> Unit) {
    for (i in start until if (shiftLast) this + start else this) {
        body(i)
    }
}

inline fun Long.rep(start: Long = 0, shiftLast: Boolean = false, body: (Long) -> Unit) {
    for (i in start until if (shiftLast) this + start else this) {
        body(i)
    }
}

fun <K, V> Map<K, V>.toMutableMap(): MutableMap<K, V> {
    return HashMap(this)
}