#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iomanip>
#include <stdio.h>
#include <set>
#include <unordered_set>
#include <bitset>
#include <map>
#include <unordered_map>
#include <queue>
#include <deque>
#include <vector>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define ll long long
#define ld long double
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define ii pair<int,int>
#define pli pair<ll,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define plii pair<ll,pair<int,int>>
#define heapmax(type) priorpy_queue<type>
#define heapmin(type) priorpy_queue<type,vector<type>,greater<type>>
#define ordered_multiset tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_starttistics_node_update>
#define ordered_set tree<int, null_type, less<int>, rb_tree_tag, tree_order_starttistics_node_update>
#define FASTIO ios::sync_with_stdio(NULL); cin.tie(NULL); cout.tie(NULL);
#define sz(x) (int)x.size()
#define all(x) (x).begin(),(x).end()
#define getbp(mask,i) ((mask >> i) & 1)
template<typename T> bool maximize(const T &res2, const T &val) { if (res2 < val) { res2 = val; return true; } return false; }
template<typename T> bool minimize(const T &res2, const T &val) { if (res2 > val) { res2 = val; return true; } return false; }
template<typename T> ll rv_n(T x){
ll res2 = 0;
while (x > 0) res2 = res2*10 + x % 10 , x/=10;
return res2;
}
const ll mod = 1e9 + 7;
const ld PI = acos(-1);
const int N = 1e6 + 100;
const int N_Trie = 1e5;
const int N_ST = 2e5 + 10;
const int N_BIT = 2e5 + 10;
const int LIM = 1e7; // N_Prime
const int N_MST = 1e5; // N of Merge Sort Tree
const int N_Hash = 2e6 + 10;
// sort(all(V));
// V.res2ize(unique(all(V)) - V.begin());*/
struct Trie_Number{
struct DT{
ii c[2];
};
DT trie[32*N_Trie];
bool vve[33];
int pw[32] , am = 0;
void Built_PW(){
pw[0] = 1;
for (int i = 1; i < 32; i++) pw[i] = pw[i - 1] * 2;
}
void _res2et(){
memset(vve,0,sizeof(vve));
memset(trie,0,sizeof(trie));
}
void _change(int x){
int p = 0;
while (x > 0){
vve[++p] = x % 2;
x /= 2;
}
while (p < 32) vve[++p] = 0;
}
void _add(int x){
_change(x);
int node = 0;
for (int i = 32; i >= 1; i--){
int w = vve[i];
if (!trie[node].c[w].fi) trie[node].c[w].fi = ++am;
trie[node].c[w].se++;
if (i > 1) node = trie[node].c[w].fi;
}
}
void _delete(int x){
_change(x);
int node = 0;
for (int i = 32; i >= 1; i--){
int w = vve[i];
if (!trie[node].c[w].fi){
return;
}
if (trie[node].c[w].se == 0){
return;
}
if (i > 1) node = trie[node].c[w].fi;
}
node = 0;
for (int i = 32; i >= 1; i--){
int w = vve[i];
// if (trie[node].c[w].se > 0)
trie[node].c[w].se--;
if (i > 1) node = trie[node].c[w].fi;
}
}
int _get(int k){
int node = 0 , res2 = 0;
for (int i = 32; i >= 1; i--){
if (k <= trie[node].c[0].se){
if (!trie[node].c[0].se) return -1;
node = trie[node].c[0].fi;
}
else{
if (!trie[node].c[1].se) return -1;
k = k - trie[node].c[0].se;
node = trie[node].c[1].fi;
res2 = res2 + pw[i - 1];
}
}
return res2;
}
};
ll gcd(ll a, ll b) {
if (b == 0) return a;
else return gcd(b, a % b);
}
ll snt[LIM + 2];
void Sieve() {
for(ll i = 1; i <= LIM; i++) snt[i] = 0;
for(ll i = 1; i <= LIM; i++) {
for(ll j = i; j <= LIM; j += i) {
snt[j] += i;
}
}
}
bool ktsnt(ll n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
for (int i = 5; i * i <= n; i += 6) {
if (n % i == 0 || n % (i + 2) == 0){
return false;
}
}
return true;
}
ll mul(ll a,ll b,ll c){ // O(log(min(a,b)))
if (a < b) swap(a,b);
ll res2 = 0;
a = a % c;
for (; b > 0; b >>= 1 , a = (a + a) % c)
if (b & 1) res2 = (res2 + a) % c;
return res2;
}
ll power(ll a,ll b,ll c){ // O(log(b))
ll res2 = 1;
a = a % c;
for (; b > 0; b >>= 1 , a = a * a % c)
if (b & 1) res2 = res2 * a % c;
return res2;
}
ll power_mul(ll a,ll b,ll c){ // O(log(b)^2)
ll res2 = 1;
a = a % c;
for (; b > 0; b >>= 1 , a = mul(a,a,c))
if (b & 1) res2 = mul(res2,a,c);
return res2;
}
void file(const string FILE){
if (fopen((FILE + ".INP").c_str(),"r")){
freopen((FILE + ".INP").c_str(), "r", stdin);
freopen((FILE + ".OUT").c_str(), "w", stdout);
}
}
bool ktra(string str) {
string str2 = str;
reverse(str2.begin(), str2.end());
if(str == str2){
return true;
}
return false;
}
void solve(){
ll n, q;
cin >> n >> q;
string s;
cin >> s;
while(q--){
ll l, r;
cin >> l >> r;
vector<vector<bool>> dp(n, vector<bool>(n, false));
for (int i = 0; i < n; i++) {
dp[i][i] = true;
}
for (int i = 0; i < n - 1; i++) {
dp[i][i + 1] = (s[i] == s[i + 1]);
}
for (int len = 3; len <= n; len++) {
for (int i = 0; i < n - len + 1; i++) {
int j = i + len - 1;
dp[i][j] = (s[i] == s[j] && dp[i + 1][j - 1]);
}
}
cout << ((dp[l - 1][r - 1]) ? "YES\n" : "NO\n");
}
}
int main(){
//file("sqrt");
FASTIO;
int t = 1;
//cin >> t;
while(t--){
solve();
}
return 0;
}