#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 6;
const int M = 2e5 + 6;
int n, dfn[N], high[N], dfs_cnt, mx[N << 1], id[N];
int nxt[N][26], link[N], len[N], cnt = 1, las = 1;
bool flag[N] = {0};
string ans[M];
char s[N], t[N], *inputT = t;
vector<int> a[N];
struct node {
  int l, r, id, len;
  char *t;
  bool operator<(const node &y) const { return r < y.r; }
} ques[N];
void insert(int c, int o) {
  int cur = ++cnt, p = las;
  len[cur] = len[las] + 1;
  las = cur;
  id[o] = cur;
  for (; p && !nxt[p][c]; p = link[p]) nxt[p][c] = cur;
  if (!p)
    link[cur] = 1;
  else {
    int q = nxt[p][c];
    if (len[q] == len[p] + 1)
      link[cur] = q;
    else {
      int clone = ++cnt;
      len[clone] = len[p] + 1;
      link[clone] = link[q];
      link[q] = link[cur] = clone;
      memcpy(nxt[clone], nxt[q], sizeof(nxt[q]));
      for (; nxt[p][c] == q; p = link[p]) nxt[p][c] = clone;
    }
  }
}
void dfs(int now) {
  dfn[now] = ++dfs_cnt;
  for (auto to : a[now]) dfs(to);
  high[now] = dfs_cnt;
}
void update(int now, int l, int r, int x, int v) {
  if (l == r) {
    mx[now] = max(mx[now], v);
    return;
  }
  if (x <= (l + r) / 2)
    update((now << 1), l, (l + r) / 2, x, v);
  else
    update((now << 1) + 1, (l + r) / 2 + 1, r, x, v);
  mx[now] = max(mx[(now << 1)], mx[(now << 1) + 1]);
}
int query(int now, int l, int r, int x, int y) {
  if (x <= l && r <= y) return mx[now];
  int an = 0;
  if (x <= (l + r) / 2) an = query((now << 1), l, (l + r) / 2, x, y);
  if (y > (l + r) / 2)
    an = max(an, query((now << 1) + 1, (l + r) / 2 + 1, r, x, y));
  return an;
}
bool check(int l, int now, int match_len) {
  int maxPos = query(1, 1, dfs_cnt, dfn[now], high[now]);
  if (maxPos - match_len + 1 >= l)
    return true;
  else
    return false;
}
bool try_next(int next, int c, int l, int match_len, int ans_id) {
  if (!next) return false;
  int maxPos = query(1, 1, dfs_cnt, dfn[next], high[next]);
  if (maxPos - match_len + 1 >= l) {
    flag[ans_id] = 1;
    ans[ans_id] += 'a' + c;
    return true;
  } else
    return false;
}
void match_t(int now, int o, int index) {
  if (ques[o].len < index) {
    for (int i = 0; i < 26; i++)
      if (try_next(nxt[now][i], i, ques[o].l, index, ques[o].id)) return;
    return;
  }
  int c = ques[o].t[index] - 'a';
  int next = nxt[now][c];
  if (!next || check(ques[o].l, next, index) == 0) {
    for (int i = c + 1; i < 26; i++)
      if (try_next(nxt[now][i], i, ques[o].l, index, ques[o].id)) return;
    return;
  } else {
    if (index <= ques[o].len) {
      match_t(next, o, index + 1);
      if (flag[ques[o].id]) {
        ans[ques[o].id] += 'a' + c;
        return;
      }
      for (int i = c + 1; i < 26; i++)
        if (try_next(nxt[now][i], i, ques[o].l, index, ques[o].id)) return;
    }
  }
}
int main() {
  scanf("%s", s + 1);
  int lens = strlen(s + 1);
  for (int i = 1; i <= lens; i++) insert(s[i] - 'a', i);
  for (int i = 1; i <= cnt; i++) a[link[i]].push_back(i);
  dfs(1);
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d %d %s", &ques[i].l, &ques[i].r, inputT + 1);
    ques[i].t = inputT;
    ques[i].id = i;
    ques[i].len = strlen(ques[i].t + 1);
    inputT += ques[i].len + 1;
  }
  sort(ques + 1, ques + 1 + n);
  for (int i = 1, r = 1; i <= n; i++) {
    for (; r <= ques[i].r; r++) update(1, 1, dfs_cnt, dfn[id[r]], r);
    match_t(1, i, 1);
  }
  for (int i = 1; i <= n; i++) {
    if (!flag[i])
      printf("-1\n");
    else {
      int l = ans[i].size();
      for (int j = l - 1; j >= 0; j--) printf("%c", ans[i][j]);
      printf("\n");
    }
  }
  return 0;
}
