#include using namespace std; // ---------------- Fast Input ---------------- struct FastScanner { static constexpr size_t BUFSIZE = 1 << 20; int idx = 0, size = 0; char buf[BUFSIZE]; inline char read() { if (idx >= size) { size = (int)fread(buf, 1, BUFSIZE, stdin); idx = 0; if (size == 0) return 0; } return buf[idx++]; } template inline bool readInt(T &out) { char c; do { c = read(); if (!c) return false; } while (c <= ' '); T sign = 1; if (c == '-') { sign = -1; c = read(); } T val = 0; while (c > ' ') { val = val * 10 + (c - '0'); c = read(); } out = val * sign; return true; } inline bool readChar(char &out) { char c; do { c = read(); if (!c) return false; } while (c <= ' '); out = c; return true; } }; // ---------------- Presence SegTree (0/1) with prev/next ---------------- struct SegTreePresence { int size0 = 0; int n = 1; vector seg; // sums (>=0) SegTreePresence() {} SegTreePresence(int sz) { init(sz); } void init(int sz) { size0 = sz; n = 1; while (n < sz) n <<= 1; seg.assign(2 * n, 0); } inline int total() const { return seg[1]; } inline void set01(int pos, int val) { // val is 0/1 int i = pos + n; if (seg[i] == val) return; seg[i] = val; for (i >>= 1; i; i >>= 1) seg[i] = seg[i<<1] + seg[i<<1|1]; } // largest index <= x with leaf==1, else -1 inline int prev_leq(int x) const { if (size0 <= 0) return -1; if (x < 0) return -1; if (x >= size0) x = size0 - 1; int i = x + n; if (seg[i]) return x; while (i > 1) { if (i & 1) { // right child if (seg[i - 1]) { i = i - 1; while (i < n) { int rc = (i<<1)|1; if (seg[rc]) i = rc; else i = (i<<1); } return i - n; } } i >>= 1; } return -1; } // smallest index >= x with leaf==1, else size0 inline int next_geq(int x) const { if (size0 <= 0) return 0; if (x < 0) x = 0; if (x >= size0) return size0; int i = x + n; if (seg[i]) return x; while (i > 1) { if ((i & 1) == 0) { // left child if (seg[i + 1]) { i = i + 1; while (i < n) { int lc = (i<<1); if (seg[lc]) i = lc; else i = lc | 1; } return i - n; } } i >>= 1; } return size0; } }; // ---------------- Mo Query ---------------- struct Query { int l, r; // inclusive 0-indexed int x; char c; // 'L' or 'R' int idx; }; int main() { FastScanner fs; int N, Q; if (!fs.readInt(N)) return 0; fs.readInt(Q); vector A(N); int maxA = 0; for (int i = 0; i < N; i++) { fs.readInt(A[i]); maxA = max(maxA, A[i]); } vector qs(Q); int maxX = 0; for (int i = 0; i < Q; i++) { int L, R, X; char c; fs.readInt(L); fs.readInt(R); fs.readInt(X); fs.readChar(c); --L; --R; qs[i] = {L, R, X, c, i}; maxX = max(maxX, X); } // ---- Coordinate compression ONLY for A-values ---- vector comp = A; sort(comp.begin(), comp.end()); comp.erase(unique(comp.begin(), comp.end()), comp.end()); int M = (int)comp.size(); // <= N vector Aid(N); for (int i = 0; i < N; i++) { Aid[i] = (int)(lower_bound(comp.begin(), comp.end(), A[i]) - comp.begin()); } // ---- Gap domain remains 0..maxV ---- int maxV = max(maxA, maxX); int SZG = maxV + 1; // gaps are in [0..maxV] // ---- Mo ordering ---- int B = max(1, (int)(N / max(1.0, sqrt((double)Q)))); sort(qs.begin(), qs.end(), [&](const Query& a, const Query& b) { int ab = a.l / B, bb = b.l / B; if (ab != bb) return ab < bb; if (ab & 1) return a.r > b.r; else return a.r < b.r; }); // ---- Structures ---- vector cntVal(M, 0); // counts per compressed id SegTreePresence segVal(M); // presence of distinct values (id) vector cntGap(SZG, 0); // counts per gap value SegTreePresence segGap(SZG); // presence of distinct gaps (d) auto add_gap = [&](int d) { auto &c = cntGap[d]; if (c++ == 0) segGap.set01(d, 1); }; auto remove_gap = [&](int d) { auto &c = cntGap[d]; if (--c == 0) segGap.set01(d, 0); }; auto add_value = [&](int id) { int v = comp[id]; int predId = segVal.prev_leq(id - 1); // distinct < v bool hasV = (cntVal[id] > 0); int succId = hasV ? id : segVal.next_geq(id); // distinct >= v (or itself) const int INFID = M; if (predId != -1 && succId != INFID) { int L = comp[predId]; int R = comp[succId]; remove_gap(R - L); add_gap(v - L); add_gap(R - v); } else if (predId != -1) { int L = comp[predId]; add_gap(v - L); } else if (succId != INFID) { int R = comp[succId]; add_gap(R - v); } if (cntVal[id]++ == 0) segVal.set01(id, 1); }; auto remove_value = [&](int id) { int v = comp[id]; int predId = segVal.prev_leq(id - 1); bool remains = (cntVal[id] >= 2); // after removing one, still exists? const int INFID = M; int succId = remains ? id : segVal.next_geq(id + 1); // next distinct > v if disappears if (predId != -1 && succId != INFID) { int L = comp[predId]; int R = comp[succId]; remove_gap(v - L); remove_gap(R - v); add_gap(R - L); } else if (predId != -1) { int L = comp[predId]; remove_gap(v - L); } else if (succId != INFID) { int R = comp[succId]; remove_gap(R - v); } if (--cntVal[id] == 0) segVal.set01(id, 0); }; vector ans(Q, -1); int curL = 0, curR = -1; for (const auto& qu : qs) { while (curL > qu.l) add_value(Aid[--curL]); while (curR < qu.r) add_value(Aid[++curR]); while (curL < qu.l) remove_value(Aid[curL++]); while (curR > qu.r) remove_value(Aid[curR--]); if (segGap.total() == 0) { ans[qu.idx] = -1; continue; } int x = qu.x; if (qu.c == 'L') { int d = segGap.prev_leq(x); ans[qu.idx] = (d == -1 ? -1 : d); } else { // 'R' int d = segGap.next_geq(x); ans[qu.idx] = (d == SZG ? -1 : d); } } // ---- Fast output ---- string out; out.reserve((size_t)Q * 12); auto push_int = [&](int x) { if (x == 0) { out += "0\n"; return; } if (x < 0) { out.push_back('-'); x = -x; } char s[16]; int n = 0; while (x) { s[n++] = char('0' + (x % 10)); x /= 10; } while (n--) out.push_back(s[n]); out.push_back('\n'); }; for (int i = 0; i < Q; i++) push_int(ans[i]); fwrite(out.data(), 1, out.size(), stdout); return 0; }