#include <bits/stdc++.h>   unsigned long long val(int i) { return i + 1; }   unsigned long long pot1[100001], pot2[100001], prec1[10][100001],       prec2[10][100001];   int v[100000];   struct Node {     unsigned long long h1, h2;     int flag;     bool valid;     int sz;     Node() {       sz = h1 = h2 = 0;       flag = -1;       valid = true;     }     Node(unsigned long long a, unsigned long long b, int c) {       h1 = a;       h2 = b;       sz = c;       flag = -1;       valid = true;     }     Node(unsigned long long a, unsigned long long b, int c, bool d) {       h1 = a;       h2 = b;       sz = c;       valid = d;       flag = -1;     }     void set(int c) { flag = c; }     void reset() { flag = -1; }     void update(int c) {       if (c == -1) return;       h1 = prec1[c][sz];       h2 = prec2[c][sz];     }     bool operator!=(const Node& n) { return h1 != n.h1 || h2 != n.h2; }   };   Node st[400000];   inline int left(int i) { return 2 * i + 1; }   inline int right(int i) { return 2 * i + 2; }   void initialize(int r, int beg, int end) {     if (beg == end) {       st[r] = Node(val(v[beg]), val(v[beg]), 1);     } else {       int h = (beg + end) / 2;       initialize(left(r), beg, h);       initialize(right(r), h + 1, end);       st[r] = Node(           (st[left(r)].h1 * pot1[st[right(r)].sz] + st[right(r)].h1) % 1000000009,           (st[left(r)].h2 * pot2[st[right(r)].sz] + st[right(r)].h2) % 1000000007,           st[left(r)].sz + st[right(r)].sz);     }   }   void update(int r, int beg, int end, int qbeg, int qend, char c) {     if (end < qbeg || beg > qend) {       if (st[r].flag != -1) {         st[r].update(st[r].flag);         if (beg != end) {           st[2 * r + 1].set(st[r].flag);           st[2 * r + 2].set(st[r].flag);         }         st[r].reset();       }       return;     }     if (beg >= qbeg && end <= qend) {       st[r].update(c);       if (beg != end) {         st[left(r)].set(c);         st[right(r)].set(c);       }       st[r].reset();     } else {       int h = (beg + end) / 2;       if (st[r].flag != -1) {         st[r].update(st[r].flag);         st[2 * r + 1].set(st[r].flag);         st[2 * r + 2].set(st[r].flag);         st[r].reset();       }       update(left(r), beg, h, qbeg, qend, c);       update(right(r), h + 1, end, qbeg, qend, c);       st[r] = Node(           (st[left(r)].h1 * pot1[st[right(r)].sz] + st[right(r)].h1) % 1000000009,           (st[left(r)].h2 * pot2[st[right(r)].sz] + st[right(r)].h2) % 1000000007,           st[right(r)].sz + st[left(r)].sz);     }   }   Node query(int r, int beg, int end, int qbeg, int qend) {     if (end < qbeg || beg > qend) return Node(0, 0, false);     if (beg >= qbeg && end <= qend) {       if (st[r].flag != -1) {         st[r].update(st[r].flag);         if (beg != end) {           st[left(r)].set(st[r].flag);           st[right(r)].set(st[r].flag);         }         st[r].reset();       }       return st[r];     } else {       if (st[r].flag != -1) {         st[r].update(st[r].flag);         st[left(r)].set(st[r].flag);         st[right(r)].set(st[r].flag);         st[r].reset();       }       Node le = query(left(r), beg, (beg + end) / 2, qbeg, qend);       Node ri = query(right(r), (beg + end) / 2 + 1, end, qbeg, qend);       if (le.valid && ri.valid)         return Node((le.h1 * pot1[ri.sz] + ri.h1) % 1000000009,                     (le.h2 * pot2[ri.sz] + ri.h2) % 1000000007, le.sz + ri.sz);       else if (le.valid)         return le;       else         return ri;     }   }   bool qquery(int r, int beg, int end, int qbeg, int qend, int d) {     int sz = qend - qbeg + 1;     if (sz <= d) return true;     if (qbeg > qend) return 0;     int sobra = sz % d;     if (sobra) {       if (query(r, beg, end, qbeg, qbeg + sobra - 1) !=           query(r, beg, end, qend - sobra + 1, qend))         return false;     }     qend -= sobra;     sz = qend - qbeg + 1;     int n = sz / d;     if (sz == d) return true;     if (n & 1) {       int b0 = qbeg, b1 = qbeg + n / 2 * d, b2 = qbeg + (n / 2 + 1) * d;       int e0 = b1 - 1, e1 = b2 - 1, e2 = qend;       if (query(r, beg, end, b0, e0) != query(r, beg, end, b2, e2) ||           query(r, beg, end, b0, b0 + d - 1) != query(r, beg, end, b1, e1))         return false;       return qquery(r, beg, end, b0, e0, d);     } else {       int b0 = qbeg, b1 = qbeg + (n + 1) / 2 * d;       int e0 = b1 - 1, e1 = qend;       if (query(r, beg, end, b0, e0) != query(r, beg, end, b1, e1)) return false;       return qquery(r, beg, end, b0, e0, d);     }   }   void precalc() {     pot1[0] = 1;     pot2[0] = 1;     for (int i = 1; i <= 100000; i++) {       pot1[i] = (pot1[i - 1] * 33) % 1000000009;       pot2[i] = (pot2[i - 1] * 33) % 1000000007;     }     for (int i = 0; i < 10; i++) {       prec1[i][0] = 0;       prec2[i][0] = 0;       for (int j = 1; j <= 100000; j++) {         prec1[i][j] = (prec1[i][j - 1] * 33 + val(i)) % 1000000009;         prec2[i][j] = (prec2[i][j - 1] * 33 + val(i)) % 1000000007;       }     }   }   int main(void) {     int n, m, k;     char s[100001];     precalc();     scanf( %d%d%d , &n, &m, &k);     scanf( %s , s);     for (int i = 0; i < n; i++) {       v[i] = s[i] -  0 ;     }     initialize(0, 0, n - 1);     for (int i = 0; i < m + k; i++) {       int cmd;       int l, r, x;       scanf( %d%d%d%d , &cmd, &l, &r, &x);       if (cmd == 1) {         l--;         r--;         update(0, 0, n - 1, l, r, x);       } else {         l--;         r--;         printf( %s n , qquery(0, 0, n - 1, l, r, x) ?  YES  :  NO );       }     }   }