#include <bits/stdc++.h>
using namespace std;
const int mod[] = {998244353, 1000000007};
const int maxn = 2E5 + 77;
long long P[maxn][2];
struct HASH {
  int h[2];
  int l;
  HASH operator+(const HASH &o) const {
    HASH ret;
    for (int i = 0; i < 2; ++i) {
      ret.h[i] = (h[i] * P[o.l][i] + o.h[i]) % mod[i];
    }
    ret.l = l + o.l;
    return ret;
  }
  bool operator==(const HASH &o) const {
    return h[0] == o.h[0] && h[1] == o.h[1];
  }
} H[maxn][2];
struct SEG {
  SEG *ch[2];
  HASH h;
  void maintain() { h = ch[0]->h + ch[1]->h; }
} * root;
void segGenTree(SEG *&tr, int L, int R, const int src[]) {
  tr = new SEG;
  if (L == R) {
    tr->h.h[0] = tr->h.h[1] = src[L] + 1;
    tr->h.l = 1;
    return;
  }
  int M = L + ((R - L) / 2);
  segGenTree(tr->ch[0], L, M, src);
  segGenTree(tr->ch[1], M + 1, R, src);
  tr->maintain();
}
HASH segQuery(SEG *tr, int L, int R, int qL, int qR) {
  if (L == qL && R == qR) return tr->h;
  int M = L + ((R - L) / 2);
  if (qR <= M)
    return segQuery(tr->ch[0], L, M, qL, qR);
  else if (qL > M)
    return segQuery(tr->ch[1], M + 1, R, qL, qR);
  else
    return segQuery(tr->ch[0], L, M, qL, M) +
           segQuery(tr->ch[1], M + 1, R, M + 1, qR);
}
void segSetVal(SEG *tr, int L, int R, int p, int v) {
  if (L == R) {
    tr->h.h[0] = tr->h.h[1] = v + 1;
    tr->h.l = 1;
    return;
  }
  int M = L + ((R - L) / 2);
  if (p <= M)
    segSetVal(tr->ch[0], L, M, p, v);
  else
    segSetVal(tr->ch[1], M + 1, R, p, v);
  tr->maintain();
}
int N, M;
char S[maxn];
struct QUERY {
  int p, l, x, d;
  HASH a;
} Q[maxn * 2];
int cq = 0;
bool by_p(const QUERY &a, const QUERY &b) { return a.p < b.p; }
int L[maxn], R[maxn], Last[1024];
void gen_last() {
  for (char c = 'a'; c <= 'z'; ++c) Last[c] = 0;
  for (int i = 1; i <= N; ++i) {
    if (Last[S[i]]) {
      L[i] = i - Last[S[i]];
    } else {
      L[i] = 0;
    }
    Last[S[i]] = i;
  }
  for (char c = 'a'; c <= 'z'; ++c) Last[c] = N + 1;
  for (int i = N; i; --i) {
    R[i] = Last[S[i]];
    Last[S[i]] = i;
  }
}
void solve() {
  int q = 0;
  for (int i = 1; i <= N; ++i) {
    while (q < cq && Q[q].p == i) {
      Q[q].a = segQuery(root, 1, N, i, i + Q[q].l - 1);
      ++q;
    }
    if (R[i] && R[i] <= N) {
      segSetVal(root, 1, N, R[i], 0);
    }
  }
}
void init_P() {
  for (int i = 0; i < 2; ++i) {
    P[0][i] = 1;
    for (int j = 1; j < maxn; ++j) P[j][i] = (P[j - 1][i] * maxn) % mod[i];
  }
}
int main() {
  init_P();
  scanf("%d%d%s", &N, &M, S + 1);
  gen_last();
  for (int i = 0; i < M; ++i) {
    int x, y, len;
    scanf("%d%d%d", &x, &y, &len);
    Q[cq++] = (QUERY){x, len, i, 0};
    Q[cq++] = (QUERY){y, len, i, 1};
  }
  sort(Q, Q + cq, by_p);
  segGenTree(root, 1, N, L);
  solve();
  for (int i = 0; i < cq; ++i) {
    H[Q[i].x][Q[i].d] = Q[i].a;
  }
  for (int i = 0; i < M; ++i) {
    if (H[i][0] == H[i][1])
      printf("YES\n");
    else
      printf("NO\n");
  }
}
