#include <bits/stdc++.h>
#include "testlib.h"

using namespace std;

#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define len(a) int(a.size())

using ll = long long;
using ld = long double;

const int Q = 1'000'000;
const ll T_max = 1'000'000'000'000'000'000ll; // 1e18

// += на отрезке, максимум на отрезке, первый элемент в массиве >= x, последний >= x, первый < x, последний < x
struct SegTree {
    vector<ll> t;
    vector<ll> t_min;
    vector<ll> mod;
    int n;

    void build(int v, int l, int r, const vector<int> &a) {
        if (r - l == 1) {
            t[v] = a[l];
            t_min[v] = a[l];
            return;
        }

        int m = (l + r) / 2;
        build(v * 2 + 1, l, m, a);
        build(v * 2, m, r, a);
        t[v] = max(t[v * 2 + 1], t[v * 2]);
        t_min[v] = min(t_min[v * 2 + 1], t_min[v * 2]);
    }

    SegTree(const vector<int> &a) : n(len(a)) {
        t.resize(4 * n);
        t_min.resize(4 * n);
        mod.resize(4 * n);
        build(1, 0, n, a);
    }

    void push(int v) {
        if (mod[v] == 0) return;

        mod[v * 2 + 1] += mod[v];
        mod[v * 2] += mod[v];
        t[v * 2 + 1] += mod[v];
        t[v * 2] += mod[v];
        t_min[v * 2 + 1] += mod[v];
        t_min[v * 2] += mod[v];

        mod[v] = 0;
    }

    void update(int v, int l, int r, int L, int R, ll val) {
        if (L <= l && r <= R) {
            t[v] += val;
            t_min[v] += val;
            mod[v] += val;
            return;
        }
        if (R <= l || r <= L) return;

        push(v);
        int m = (l + r) / 2;
        update(v * 2 + 1, l, m, L, R, val);
        update(v * 2, m, r, L, R, val);
        t[v] = max(t[v * 2 + 1], t[v * 2]);
        t_min[v] = min(t_min[v * 2 + 1], t_min[v * 2]);
    }

    void update(int l, int r, ll val) {
        update(1, 0, n, l, r, val);
    }

    int get_first_geq(int v, int l, int r, ll val) {
        if (t[v] < val) return -1;
        if (r - l == 1) return l;

        int m = (l + r) / 2;
        push(v);
        int res = get_first_geq(v * 2 + 1, l, m, val);
        if (res == -1) res = get_first_geq(v * 2, m, r, val);
        return res;
    }

    int get_first_geq(ll val) {
        return get_first_geq(1, 0, n, val);
    }

    int get_last_geq(int v, int l, int r, ll val) {
        if (t[v] < val) return -1;
        if (r - l == 1) return l;

        int m = (l + r) / 2;
        push(v);
        int res = get_last_geq(v * 2, m, r, val);
        if (res == -1) return get_last_geq(v * 2 + 1, l, m, val);
        return res;
    }

    int get_last_geq(ll val) {
        return get_last_geq(1, 0, n, val);
    }

    int get_first_le(int v, int l, int r, ll val) {
        if (t_min[v] >= val) return -1;
        if (r - l == 1) return l;

        int m = (l + r) / 2;
        push(v);
        int res = get_first_le(v * 2 + 1, l, m, val);
        if (res == -1) res = get_first_le(v * 2, m, r, val);
        return res;
    }

    int get_first_le(ll val) {
        return get_first_le(1, 0, n, val);
    }

    int get_last_le(int v, int l, int r, ll val) {
        if (t_min[v] >= val) return -1;
        if (r - l == 1) return l;

        int m = (l + r) / 2;
        push(v);
        int res = get_last_le(v * 2, m, r, val);
        if (res == -1) return get_last_le(v * 2 + 1, l, m, val);
        return res;
    }

    int get_last_le(ll val) {
        return get_last_le(1, 0, n, val);
    }

    ll get_val(int v, int l, int r, int pos) {
        if (r - l == 1) return t[v];

        int m = (l + r) / 2;
        push(v);
        if (pos < m) return get_val(v * 2 + 1, l, m, pos);
        else return get_val(v * 2, m, r, pos);
    }

    ll get_max(int v, int l, int r, int L, int R) {
        if (L <= l && r <= R) return t[v];
        if (R <= l || r <= L) return 0;

        int m = (l + r) / 2;
        push(v);
        return max(get_max(v * 2 + 1, l, m, L, R), get_max(v * 2, m, r, L, R));
    }

    ll get_max(int l, int r) {
        return get_max(1, 0, n, l, r);
    }

    ll get_val(int pos) {
        return get_val(1, 0, n, pos);
    }
};


int readAns(int T, int n, int m, vector<int> a, InStream &in) {
    string token_result = lowerCase(in.readToken("[YESyesNOno]{2,3}", "yes/no token")); // TODO: считывать через регулярку
    if (token_result != "no" && token_result != "yes") {
        in.quitf(_wa, "Unknown token.");
    }
    if (token_result == "no") return -1;
    if (T == 1) return 0;

    int res = in.readInt(1, m, "Remaining plot size");
    if (T == 2) return res;

    int q = in.readInt(0, Q, "q");
    int cur_size = m;
    vector<pair<ll, int>> queries(q);
    for (int i = 0; i < q; ++i) {
        queries[i].first = in.readLong(0, T_max, "t");
        queries[i].second = in.readInt(1, cur_size - 1, "x");
        cur_size = queries[i].second;
    }
    if (cur_size != res) {
        in.quitf(_wa, "The remaining plot size does not match the printed size.");
    }

    SegTree t(a);
    cur_size = m;
    ll lst_time = 0;

    // Получает по позиции на "круге" позицию овцы внутри участка
    auto get_cord = [&](ll x) -> ll {
        if (x < cur_size) return x;
        return 2 * cur_size - 2 - x;
    };

    for (int i = 0; i < q; ++i) {
        if (lst_time > queries[i].first) {
            in.quit(_wa, "You should print times in chronological order.");
        }

        // Добавляем ко всем овцам, насколько они сдвинулись по кругу
        ll d_time = queries[i].first - lst_time;
        lst_time = queries[i].first;
        t.update(0, n, d_time % (2 * cur_size - 2));

        // mod= 2 * cur_size - 2. (То есть мы хотим оставить цикл по модулю_
        int i3 = t.get_first_geq(2 * cur_size - 2);
        int i4 = t.get_last_geq(2 * cur_size - 2);

        if (i3 != -1) { // Само обновление.
            /*
             * i3, i4 - самый первый/последний больший
             * i33, i44 - самый первый/последний меньший.
             * У нас массив - это циклический сдвиг отсортированного массива
             * Поэтому, есть два случая, у нас элементы >= 2 * cur_size - 2 лежат на отрезке, либо же на суффиксе + префиксе
             * Если у нас они лежат на отрезке, который не касается концов, то у нас правее i3 находится i33
             * Аналогично i4 левее i44. Поэтому проверка i33 < i3 && i4 < i44 означает, что отрезок вложен
             * Иначе у нас до i33 лежат элементы большие, а после i44 - меньшие.
             * Также аналогичная проверка, когда уменьшаем круг
            */
            int i33 = t.get_first_le(2 * cur_size - 2);
            int i44 = t.get_last_le(2 * cur_size - 2);
            ll val = 2 * cur_size - 2;
            if (i33 < i3 && i4 < i44) {
                t.update(i3, i4 + 1, -val);
            } else {
                t.update(0, i33, -val);
                t.update(i44 + 1, n, -val);
            }
        }

        // Собираем самые дальние овцы
        int i1 = t.get_first_geq(cur_size - 1);
        int i2 = t.get_last_geq(cur_size - 1);
        int i111 = t.get_first_le(cur_size - 1);
        int i222 = t.get_last_le(cur_size - 1);
        // У нас кандидаты на самые дальние - это минимум из тех, кто больше m - 1, и максимум из меньших.
        // Поэтому можно заметить, что оптимум находится среди первый/последний из меньших/больших +-1
        vector<int> opt = {i1, i2, i111, i222};
        // Это ответы, если у нас нет тех, кто идет влево/вправо
        ll mx = max(get_cord(t.t[1]), get_cord(t.t_min[1]));

        for (int dt = -1; dt <= 1; ++dt) {
            for (int i : opt) {
                if (i + dt >= 0 && i + dt < len(a)) {
                    mx = max(mx, get_cord(t.get_val(i + dt)));
                }
            }
        }
        if (mx + 1 > queries[i].second) {
            in.quitf(_wa, "There is a sheep to the right of the new boundary.");
        }

        // Сдвигаем по циклу тех, кто идет на лево на дельту цикла
        if (i1 != -1) {
            ll val1 = cur_size - 1;
            ll val2 = -2 * (cur_size - queries[i].second);
            int i11 = t.get_first_le(val1);
            int i22 = t.get_last_le(val1);

            if (i11 < i1 && i2 < i22) {
                t.update(i1, i2 + 1, val2);
            } else {
                t.update(0, i11, val2);
                t.update(i22 + 1, n, val2);
            }
        }
        cur_size = queries[i].second;
    }

    if (cur_size == 1) return res;
    for (int i = 0; i < n; ++i) {
        if (t.get_val(0) != t.get_val(i)) {
            in.quitf(_wa, "Not all sheep move in the same way.");
        }
    }
    return res;
}

int main(int argc, char* argv[]) {
    registerTestlibCmd(argc, argv);

    int T = inf.readInt();
    int n = inf.readInt();
    int m = inf.readInt();

    vector<int> a = inf.readInts(n);
    string s = inf.readToken();

    for (int i = 0; i < n; ++i) {
        if (s[i] == 'L') a[i] = 2 * m - a[i];
        --a[i];
    }
    sort(all(a));

    int jans = readAns(T, n, m, a, ans);
    int pans = readAns(T, n, m, a, ouf);
    if (jans != pans) {
        if (T != 3) {
            quitf(_wa, "wrong answer");
        }
        if (jans == -1 && pans != -1) {
            quitf(_fail, "пупупупупупупупупупупу pans find, but jury don't");
        }
        if (pans == -1 && jans != -1) {
            quitf(_wa, "Jury find the answer, but partipiciant not.");
        }
        if (pans > jans) {
            quitf(_fail, "пупупупупупупупупупу pans better solution");
        } else {
            quitf(_wa, "Jury find the better answer");
        }
    }
    quitf(_ok, "You're awesome!");
}