import sys

sys.setrecursionlimit(1 << 25)

read = sys.stdin.readline

ra = range

enu = enumerate





def read_ints():

    return list(map(int, read().split()))





def read_a_int():

    return int(read())





def read_tuple(H):

    '''

    H is number of rows

    '''

    ret = []

    for _ in range(H):

        ret.append(tuple(map(int, read().split())))

    return ret





def read_col(H):

    '''

    H is number of rows

    A列、B列が与えられるようなとき

    ex1)A,B=read_col(H)    ex2) A,=read_col(H) #一列の場合

    '''

    ret = []

    for _ in range(H):

        ret.append(list(map(int, read().split())))

    return tuple(map(list, list(zip(*ret))))





def read_matrix(H):

    '''

    H is number of rows

    '''

    ret = []

    for _ in range(H):

        ret.append(list(map(int, read().split())))

    return ret

    # return [list(map(int, read().split())) for _ in range(H)] # 内包表記はpypyでは遅いため





MOD = 10**9 + 7

INF = 2**31  # 2147483648 > 10**9

# default import

from collections import defaultdict, Counter, deque

from operator import itemgetter

from itertools import product, permutations, combinations

from bisect import bisect_left, bisect_right  # , insort_left, insort_right



# https://atcoder.jp/contests/abc049/tasks/arc065_a

# まえからっ読んでいくと文字列のオーバーラップが多くいし、末尾のオーバーラップも多くてしんどい

# 逆から読んでくと3文字で即時決定できる



S = read()[:-1]

S = deque(reversed('xxxxxxxxxx' + S))  # よしなにpaddingすることで終端処理を楽に



# print(S)

while len(S) > 10:

    end3 = ''.join([S[6], S[5], S[4], S[3], S[2], S[1], S[0]])

    # print(end3)

    if end3[2:] == 'dream':

        num_pop = 5

    elif end3 == 'dreamer':

        num_pop = 7

    elif end3[2:] == 'erase':

        num_pop = 5

    elif end3[1:] == 'eraser':

        num_pop = 6

    else:

        print('NO')

        exit()

    for _ in ra(num_pop):

        S.popleft()



# print(S)

if len(S) == 10:

    print('YES')

else:

    print('NO')

mycode = r'''

# distutils: language=c++

# cython: language_level=3

# cython: boundscheck=False

# cython: wraparound=False

# cython: infer_types=True

# cython: cdivision=True

# False:Cython はCの型に対する除算・剰余演算子に関する仕様を、(被演算子間の符号が異なる場合の振る舞いが異なる)Pythonのintの仕様に合わせ、除算する数が0の場合にZeroDivisionErrorを送出します。この処理を行わせると、速度に 35% ぐらいのペナルティが生じます。 True:チェックを行いません。



from libcpp.string cimport string as Str

# define 

ctypedef long long LL



# 読み込みはpython側で行う

import sys

readline = sys.stdin.buffer.readline().rstrip



cdef LL i,j,k,_





cdef Str S = readline()

cdef Str dream = b'dream'

cdef Str dreamer = b'dreamer'

cdef Str erase = b'erase'

cdef Str eraser = b'eraser'



# 文字列処理は流石にpypy提出のほうが楽そう

# 致命的な点としては、libcpp.stringがeraseなどの文字列削除操作に対応していない点だ



cdef LL idx=S.size()

while idx>7:

    if S.substr(idx-5,5)==dream: #idxから後ろ5文字以降を表示

        idx-=5 

    elif S.substr(idx-5,5)==erase:

        idx-=5 

    elif S.substr(idx-6,6)==eraser:

        idx-=6

    elif S.substr(idx-7,7)==dreamer:

        idx-=7 

    else: break



#print(S,idx,S.substr(idx))

if S.substr(0, idx) in [dream, dreamer, erase, eraser]:

    print('YES')

else:

    print('NO')







'''



import sys

if sys.argv[-1] == 'ONLINE_JUDGE':  # コンパイル時

    import os

    with open('mycode.pyx', 'w') as f:

        f.write(mycode)

    os.system('cythonize -i -3 -b mycode.pyx')



import mycode

import sys

sys.setrecursionlimit(1 << 25)
read = sys.stdin.readline
ra = range
enu = enumerate


def read_ints():
    return list(map(int, read().split()))


def read_a_int():
    return int(read())


def read_tuple(H):
    """
    H is number of rows
    """
    ret = []
    for _ in range(H):
        ret.append(tuple(map(int, read().split())))
    return ret


def read_col(H):
    """
    H is number of rows
    A列、B列が与えられるようなとき
    ex1)A,B=read_col(H)    ex2) A,=read_col(H) #一列の場合
    """
    ret = []
    for _ in range(H):
        ret.append(list(map(int, read().split())))
    return tuple(map(list, list(zip(*ret))))


def read_matrix(H):
    """
    H is number of rows
    """
    ret = []
    for _ in range(H):
        ret.append(list(map(int, read().split())))
    return ret
    # return [list(map(int, read().split())) for _ in range(H)] # 内包表記はpypyでは遅いため


MOD = 10**9 + 7
INF = 2**31  # 2147483648 > 10**9
# default import
from collections import defaultdict, Counter, deque
from operator import itemgetter
from itertools import product, permutations, combinations
from bisect import bisect_left, bisect_right  # , insort_left, insort_right

# https://atcoder.jp/contests/abc049/tasks/arc065_a
# まえからっ読んでいくと文字列のオーバーラップが多くいし、末尾のオーバーラップも多くてしんどい
# 逆から読んでくと3文字で即時決定できる
S = read()[:-1]
S = deque(reversed("xxxxxxxxxx" + S))  # よしなにpaddingすることで終端処理を楽に
# print(S)
while len(S) > 10:
    end3 = "".join([S[6], S[5], S[4], S[3], S[2], S[1], S[0]])
    # print(end3)
    if end3[2:] == "dream":
        num_pop = 5
    elif end3 == "dreamer":
        num_pop = 7
    elif end3[2:] == "erase":
        num_pop = 5
    elif end3[1:] == "eraser":
        num_pop = 6
    else:
        print("NO")
        exit()
    for _ in ra(num_pop):
        S.popleft()
# print(S)
if len(S) == 10:
    print("YES")
else:
    print("NO")

mycode = r"""
# distutils: language=c++
# cython: language_level=3
# cython: boundscheck=False
# cython: wraparound=False
# cython: infer_types=True
# cython: cdivision=True
# False:Cython はCの型に対する除算・剰余演算子に関する仕様を、(被演算子間の符号が異なる場合の振る舞いが異なる)Pythonのintの仕様に合わせ、除算する数が0の場合にZeroDivisionErrorを送出します。この処理を行わせると、速度に 35% ぐらいのペナルティが生じます。 True:チェックを行いません。
from libcpp.string cimport string as Str
# define 
ctypedef long long LL
# 読み込みはpython側で行う
import sys
readline = sys.stdin.buffer.readline().rstrip
cdef LL i,j,k,_
cdef Str S = readline()
cdef Str dream = b'dream'
cdef Str dreamer = b'dreamer'
cdef Str erase = b'erase'
cdef Str eraser = b'eraser'
# 文字列処理は流石にpypy提出のほうが楽そう
# 致命的な点としては、libcpp.stringがeraseなどの文字列削除操作に対応していない点だ
cdef LL idx=S.size()
while idx>7:
    if S.substr(idx-5,5)==dream: #idxから後ろ5文字以降を表示
        idx-=5 
    elif S.substr(idx-5,5)==erase:
        idx-=5 
    elif S.substr(idx-6,6)==eraser:
        idx-=6
    elif S.substr(idx-7,7)==dreamer:
        idx-=7 
    else: break
#print(S,idx,S.substr(idx))
if S.substr(0, idx) in [dream, dreamer, erase, eraser]:
    print('YES')
else:
    print('NO')
"""
import sys

if sys.argv[-1] == "ONLINE_JUDGE":  # コンパイル時
    import os

    with open("mycode.pyx", "w") as f:
        f.write(mycode)
    os.system("cythonize -i -3 -b mycode.pyx")
import mycode

+mycode = r""" +# distutils: language=c++ +# cython: language_level=3 +# cython: boundscheck=False +# cython: wraparound=False +# cython: infer_types=True +# cython: cdivision=True +# False:Cython はCの型に対する除算・剰余演算子に関する仕様を、(被演算子間の符号が異なる場合の振る舞いが異なる)Pythonのintの仕様に合わせ、除算する数が0の場合にZeroDivisionErrorを送出します。この処理を行わせると、速度に 35% ぐらいのペナルティが生じます。 True:チェックを行いません。 +from libcpp.string cimport string as Str +# define +ctypedef long long LL +# 読み込みはpython側で行う +import sys +readline = sys.stdin.buffer.readline().rstrip +cdef LL i,j,k,_ +cdef Str S = readline() +cdef Str dream = b'dream' +cdef Str dreamer = b'dreamer' +cdef Str erase = b'erase' +cdef Str eraser = b'eraser' +# 文字列処理は流石にpypy提出のほうが楽そう +# 致命的な点としては、libcpp.stringがeraseなどの文字列削除操作に対応していない点だ +cdef LL idx=S.size() +while idx>7: +    if S.substr(idx-5,5)==dream: #idxから後ろ5文字以降を表示 +        idx-=5 +    elif S.substr(idx-5,5)==erase: +        idx-=5 +    elif S.substr(idx-6,6)==eraser: +        idx-=6 +    elif S.substr(idx-7,7)==dreamer: +        idx-=7 +    else: break +#print(S,idx,S.substr(idx)) +if S.substr(0, idx) in [dream, dreamer, erase, eraser]: +    print('YES') +else: +    print('NO') +""" -sys.setrecursionlimit(1 << 25) -read = sys.stdin.readline -ra = range -enu = enumerate +if sys.argv[-1] == "ONLINE_JUDGE":  # コンパイル時 +    import os - -def read_ints(): -    return list(map(int, read().split())) - - -def read_a_int(): -    return int(read()) - - -def read_tuple(H): -    """ -    H is number of rows -    """ -    ret = [] -    for _ in range(H): -        ret.append(tuple(map(int, read().split()))) -    return ret - - -def read_col(H): -    """ -    H is number of rows -    A列、B列が与えられるようなとき -    ex1)A,B=read_col(H)    ex2) A,=read_col(H) #一列の場合 -    """ -    ret = [] -    for _ in range(H): -        ret.append(list(map(int, read().split()))) -    return tuple(map(list, list(zip(*ret)))) - - -def read_matrix(H): -    """ -    H is number of rows -    """ -    ret = [] -    for _ in range(H): -        ret.append(list(map(int, read().split()))) -    return ret -    # return [list(map(int, read().split())) for _ in range(H)] # 内包表記はpypyでは遅いため - - -MOD = 10**9 + 7 -INF = 2**31  # 2147483648 > 10**9 -# default import -from collections import defaultdict, Counter, deque -from operator import itemgetter -from itertools import product, permutations, combinations -from bisect import bisect_left, bisect_right  # , insort_left, insort_right - -# https://atcoder.jp/contests/abc049/tasks/arc065_a -# まえからっ読んでいくと文字列のオーバーラップが多くいし、末尾のオーバーラップも多くてしんどい -# 逆から読んでくと3文字で即時決定できる -S = read()[:-1] -S = deque(reversed("xxxxxxxxxx" + S))  # よしなにpaddingすることで終端処理を楽に -# print(S) -while len(S) > 10: -    end3 = "".join([S[6], S[5], S[4], S[3], S[2], S[1], S[0]]) -    # print(end3) -    if end3[2:] == "dream": -        num_pop = 5 -    elif end3 == "dreamer": -        num_pop = 7 -    elif end3[2:] == "erase": -        num_pop = 5 -    elif end3[1:] == "eraser": -        num_pop = 6 -    else: -        print("NO") -        exit() -    for _ in ra(num_pop): -        S.popleft() -# print(S) -if len(S) == 10: -    print("YES") -else: -    print("NO") +    with open("mycode.pyx", "w") as f: +        f.write(mycode) +    os.system("cythonize -i -3 -b mycode.pyx") +import mycode