#include <bits/stdc++.h>
using namespace std;
void RI() {}
template <typename... T>
void RI(int &head, T &...tail) {
  scanf("%d", &head);
  RI(tail...);
}
struct StrHash {
  const static int P = 100;
  const static int N = 1e5 + 10;
  constexpr static int MOD[] = {1000000123, 1000001011, 1000009999};
  const static int N_MOD = sizeof(MOD) / sizeof(MOD[0]);
  struct PowTable {
    int64_t dat[N][N_MOD];
    PowTable() {
      for (int i = 0; i < N_MOD; i++) dat[0][i] = 1;
      for (int i = 1; i < N; i++)
        for (int j = 0; j < N_MOD; j++) dat[i][j] = dat[i - 1][j] * P % MOD[j];
    }
    int64_t *operator[](int i) { return dat[i]; }
  };
  static PowTable pw;
  int len;
  array<int64_t, N_MOD> val;
  StrHash(const char *s = "") {
    len = 0;
    val.fill(0);
    while (*s) (*this) += *s;
  }
  StrHash(int x) {
    len = 1;
    for (int i = 0; i < N_MOD; i++) val[i] = x % MOD[i];
  }
  StrHash(const string &s) : StrHash(s.data()) {}
  bool operator==(StrHash &o) { return len == o.len && val == o.val; }
  int64_t &operator[](int i) { return val[i]; }
  int64_t operator[](int i) const { return val[i]; }
  StrHash operator+(const StrHash &o) const {
    StrHash s;
    s.len = len + o.len;
    for (int i = 0; i < N_MOD; i++)
      s[i] = (val[i] * pw[o.len][i] + o[i]) % MOD[i];
    return s;
  }
  void operator+=(const StrHash &o) {
    len += o.len;
    for (int i = 0; i < N_MOD; i++)
      val[i] = (val[i] * pw[o.len][i] + o[i]) % MOD[i];
  }
  StrHash operator+(int x) {
    StrHash s;
    s.len = len + 1;
    for (int i = 0; i < N_MOD; i++) s[i] = (val[i] * P + x) % MOD[i];
    return s;
  }
  void operator+=(int x) {
    len++;
    for (int i = 0; i < N_MOD; i++) val[i] = (val[i] * P + x) % MOD[i];
  }
};
StrHash::PowTable StrHash::pw;
constexpr int StrHash::MOD[];
const int N = 1e5 + 10;
StrHash tbl[10][N];
struct Seg {
  int cov[4 * N];
  StrHash h[4 * N];
  StrHash get_h(int id, int l, int r) {
    if (cov[id] == -1)
      return h[id];
    else
      return tbl[cov[id]][r - l + 1];
  }
  void push(int id) {
    int &c = cov[id];
    if (c == -1) return;
    cov[id * 2] = cov[id * 2 + 1] = c;
    c = -1;
  }
  void pull(int id, int l, int m, int r) {
    h[id] = get_h(id * 2, l, m) + get_h(id * 2 + 1, m + 1, r);
  }
  void init(int id, int l, int r, int *a) {
    cov[id] = -1;
    if (l == r) {
      h[id] = StrHash(a[l] + 1);
      return;
    }
    int m = (l + r) / 2;
    init(id * 2, l, m, a);
    init(id * 2 + 1, m + 1, r, a);
    pull(id, l, m, r);
  }
  StrHash ask(int id, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) return get_h(id, l, r);
    int m = (l + r) / 2;
    push(id);
    StrHash ret;
    if (ql <= m) ret += ask(id * 2, l, m, ql, qr);
    if (qr > m) ret += ask(id * 2 + 1, m + 1, r, ql, qr);
    pull(id, l, m, r);
    return ret;
  }
  void set(int id, int l, int r, int ql, int qr, int qc) {
    if (ql <= l && r <= qr) {
      cov[id] = qc;
      return;
    }
    push(id);
    int m = (l + r) / 2;
    if (ql <= m) set(id * 2, l, m, ql, qr, qc);
    if (qr > m) set(id * 2 + 1, m + 1, r, ql, qr, qc);
    pull(id, l, m, r);
  }
} seg;
int n, q1, q2, a[N];
int main() {
  RI(n, q1, q2);
  for (int i = (1); i <= int(n); i++) scanf("%1d", a + i);
  for (int i = 0; i < int(10); i++)
    for (int j = 0; j < int(n); j++) tbl[i][j + 1] = tbl[i][j] + (i + 1);
  seg.init(1, 1, n, a);
  for (int i = 0; i < int(q1 + q2); i++) {
    int op, l, r, c;
    RI(op, l, r, c);
    if (op == 1)
      seg.set(1, 1, n, l, r, c);
    else {
      if (c == r - l + 1) {
        puts("YES");
        continue;
      }
      auto h1 = seg.ask(1, 1, n, l, r - c);
      auto h2 = seg.ask(1, 1, n, l + c, r);
      puts(h1 == h2 ? "YES" : "NO");
    }
  }
  return 0;
}
