
fun main(args: Array<String>) {
    while(true) {
        val str = (readLine() ?: break).trim().filter(Char::isLetter).map(Char::toUpperCase).joinToString(" ")
        val palindrome = longestOddPalindrome(str)
        val odd = palindrome.indices.filter{str[it] != ' ' && palindrome[it] >= 3}.map{str.substring(it, it + palindrome[it]).filter(Char::isLetter)}.sorted()
        val even = palindrome.indices.filter{str[it] == ' ' && palindrome[it] >= 4}.map{str.substring(it, it + palindrome[it]).filter(Char::isLetter)}.sorted()

        println(
                (odd.indices.filter{it + 1 !in odd.indices || odd[it].length > odd[it + 1].length || odd[it] != odd[it + 1].substring(0, odd[it].length)}.map{odd[it].reversed() + odd[it].drop(1)} + even.indices.filter{it + 1 !in even.indices || even[it].length > even[it + 1].length || even[it] != even[it + 1].substring(0, odd[it].length)}.map{even[it].reversed() + even[it]}).joinToString(" ")
        )
    }
}
fun longestOddPalindrome(state: String): IntArray {
    val result = IntArray(state.length){1}
    var i = 0
    while (i < result.size) {
        while ((i - result[i]) in state.indices && (i + result[i]) in state.indices && state[i - result[i]] == state[i + result[i]])
            ++result[i]
        for (k in 1 .. result[i]) {
            if (i - k in result.indices && result[i - k] + k < result[i]) {
                result[i + k] = result[i - k]
            }else {
                if (k != result[i]) result[i + k] = result[i] - k
                i += k
                break
            }
        }
    }
    return result
}
