import java.io.BufferedReader import java.io.InputStream import java.io.InputStreamReader import java.util.* import kotlin.math.abs import kotlin.math.max import kotlin.math.min val MOD = 1_000_000_007 class Solver(stream: InputStream, private val out: java.io.PrintWriter) { fun solve() { val base = ns() val N = base.length val S = CharArray(N + 2) val next = IntArray(N + 2) val prev = IntArray(N + 2) val ps = mutableSetOf() val es = mutableSetOf() val hs = mutableSetOf() next[0] = 1 prev[N + 1] = N for (i in 1..N) { next[i] = i + 1 prev[i] = i - 1 S[i] = base[i - 1] when { S[i] == 'p' -> ps += i S[i] == 'h' -> hs += i S[i] == 'e' -> es += i } } fun testWord(s: Int, word: String, i: Int): Boolean { if (i == word.length) return true if (S[s] != word[i]) return false return testWord(next[s], word, i + 1) } fun startsWithPhnom(i: Int) = testWord(i, "phnom",0) fun replaceWithWord(s: Int, word: String, i: Int): Int { if (i == word.length) return s S[s] = word[i] return replaceWithWord(next[s], word, i + 1) } fun removeChar(i: Int) { prev[next[i]] = prev[i] next[prev[i]] = next[i] } fun replaceWithPenh(i: Int) { val ix_m = replaceWithWord(i, "penh", 0) removeChar(ix_m) S[next[i]] = 'e' hs -= next[i] es += next[i] hs += prev[ix_m] } fun findPrev(i: Int, c: Char, cnt: Int): Int { if (prev[i] == 0 || cnt == 0) return -1 if (S[prev[i]] == c) return prev[i] return findPrev(prev[i], c, cnt - 1) } fun printS() { if (isDebug) { val str = StringBuffer() var i = next[0] while (i < N + 1) { str.append(S[i]) i = next[i] } debug { str.toString() } } } var ans = 0 loop@while(ps.isNotEmpty() || es.isNotEmpty() || hs.isNotEmpty()) { debug{"$ps $hs $es $ans"} printS() val itr_p = ps.iterator() while(itr_p.hasNext()) { val i = itr_p.next() itr_p.remove() if (startsWithPhnom(i)) { ++ans replaceWithPenh(i) continue@loop } } if (es.isNotEmpty() || hs.isNotEmpty()) { ++ans val itr_h = hs.iterator() while(itr_h.hasNext()) { val i = itr_h.next() itr_h.remove() removeChar(i) val ixP = findPrev(i, 'p', 4) if (ixP != -1) ps += ixP } val itr_e = es.iterator() while(itr_e.hasNext()) { val i = itr_e.next() itr_e.remove() S[i] = 'h' hs += i if (prev[i] != -1 && S[i] == 'p') ps += prev[i] } } } out.println(ans) } private val isDebug = try { // なんか本番でエラーでる System.getenv("MY_DEBUG") != null } catch (t: Throwable) { false } private var tokenizer: StringTokenizer? = null private val reader = BufferedReader(InputStreamReader(stream), 32768) private fun next(): String { while (tokenizer == null || !tokenizer!!.hasMoreTokens()) { tokenizer = StringTokenizer(reader.readLine()) } return tokenizer!!.nextToken() } private fun ni() = next().toInt() private fun nl() = next().toLong() private fun ns() = next() private fun na(n: Int, offset: Int = 0): IntArray { return map(n, offset) { ni() } } private inline fun map(n: Int, offset: Int = 0, f: (Int) -> Int): IntArray { val res = IntArray(n) for (i in 0 until n) { res[i] = f(i + offset) } return res } private inline fun debug(msg: () -> String) { if (isDebug) System.err.println(msg()) } private fun debug(a: LongArray) { debug { a.joinToString(" ") } } private fun debug(a: IntArray) { debug { a.joinToString(" ") } } private fun debug(a: BooleanArray) { debug { a.map { if (it) 1 else 0 }.joinToString("") } } private fun debugDim(A: Array) { if (isDebug) { for (a in A) { debug(a) } } } /** * 勝手にimport消されるのを防ぎたい */ private fun hoge() { min(1, 2) max(1, 2) abs(-10) } } fun pair(a: A, b: B) = RPair(a, b) data class RPair(val _1: A, val _2: B) fun main() { val out = java.io.PrintWriter(System.out) Solver(System.`in`, out).solve() out.flush() }