Problem:
Score : 300 points

Problem Statement

You are given a string S consisting of lowercase English letters.
Another string T is initially empty.
Determine whether it is possible to obtain S = T by performing the following operation an arbitrary number of times:

Append one of the following at the end of T: dream, dreamer, erase and eraser.

Constraints

1≦|S|≦10^5

S consists of lowercase English letters.

Input

The input is given from Standard Input in the following format:

S

Output

If it is possible to obtain S = T, print YES. Otherwise, print NO.

Sample Input 1

erasedream

Sample Output 1

YES

Append erase and dream at the end of T in this order, to obtain S = T.

Sample Input 2

dreameraser

Sample Output 2

YES

Append dream and eraser at the end of T in this order, to obtain S = T.

Sample Input 3

dreamerer

Sample Output 3

NO

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>

#define NREP() for(ll i = 0; i < n; i++)
#define MREP() for(ll j = 0; j < m; j++)
#define REP(i, x, y) for(ll i = x; i < y; i++)
#define ALL(x) (x).begin(), (x).end()
#define MSG(x) cout << x << endl;
#define MSGF(x, n) MSG(fixed << setprecision(n) << x)
#define END(x) cout << x << endl; exit(0);
#define IPT(v, n) REP(i, 0, n){ cin >> v[i]; }
#define YN(x) x ? cout << "YES" << endl : cout << "NO" << endl;
#define Yn(x) x ? cout << "Yes" << endl : cout << "No" << endl;
#define yn(x) x ? cout << "yes" << endl : cout << "no" << endl;

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<ll> vl;
typedef vector<vector<ll>> vvl;
typedef vector<ull> vul;
typedef vector<vector<ull>> vvul;
typedef vector<char> vc;
typedef vector<vector<char>> vvc;
typedef vector<string> vs;
typedef vector<vector<string>> vvs;

const static ll MOD = 1e9 + 7;
const static ll INF = 1LL << 30;

ll a, b, c, d, k, l, m, n, h, w, q, x, y;
string s, t;

ull ans = 0;
ll sum = 0;
ll cnt = 0;
ull cur = 0;
ll tmp = 0;
ll mini = INF;
ll maxi = 0;

double ave = 0.0;

bool can_make = false;

void dfs(string str) {
    if (str != s.substr(0, str.length())) return;

    if (str.length() >= s.length()) {
        if (str == s && !can_make) {
            can_make = true;
        }
        return;
    }

    if (s.at(str.size()) == 'd') {
        dfs(str + "dream");
        dfs(str + "dreamer");
    } else {
        dfs(str + "erase");
        dfs(str + "eraser");
    }
}

int main() {
    cin >> s;
    reverse(ALL(s));
    ll idx = 0;
    while (true) {
        if (s.substr(idx,  5) == "maerd" ||
            s.substr(idx,  5) == "esare") {
            idx += 5;
        } else if (s.substr(idx,  6) == "resare") {
            idx += 6;
        } else if (s.substr(idx,  7) == "remaerd") {
            idx += 7;
        } else {
            END("NO")
        }

        if (idx == s.size()) {
            END("YES")
        }
    }
}