#include <bits/stdc++.h>
const int N = 2e5;
using namespace std;
int n, q;
char ch[N + 5], t[N + 5];
struct Seg {
  int lc[N * 80 + 5], rc[N * 80 + 5], node_cnt;
  bool s[N * 80 + 5];
  void pushup(int k) { s[k] = s[lc[k]] | s[rc[k]]; }
  void insert(int &k, int l, int r, int x) {
    if (!k) k = ++node_cnt;
    if (l == r) {
      s[k] = 1;
      return;
    }
    int mid = l + r >> 1;
    if (x <= mid)
      insert(lc[k], l, mid, x);
    else
      insert(rc[k], mid + 1, r, x);
    pushup(k);
  }
  int merge(int x, int y, int l, int r) {
    if (!x || !y) return x + y;
    int k = ++node_cnt;
    s[k] = s[x] | s[y];
    if (l == r) return k;
    int mid = l + r >> 1;
    lc[k] = merge(lc[x], lc[y], l, mid);
    rc[k] = merge(rc[x], rc[y], mid + 1, r);
    pushup(k);
    return k;
  }
  bool query(int k, int l, int r, int x, int y) {
    if (x > y) return 0;
    if (!k) return 0;
    if (l >= x && r <= y) return s[k];
    int mid = l + r >> 1;
    if (y <= mid) return query(lc[k], l, mid, x, y);
    if (x > mid) return query(rc[k], mid + 1, r, x, y);
    return query(lc[k], l, mid, x, y) | query(rc[k], mid + 1, r, x, y);
  }
} tree;
struct SAM {
  int ch[N * 2 + 5][26], fa[N * 2 + 5], len[N * 2 + 5], node_cnt, las,
      ep[N * 2 + 5], edge[N * 2 + 5], nxt[N * 2 + 5], head[N * 2 + 5], edge_cnt,
      rt[N * 2 + 5];
  char ans[N + 5];
  SAM() { node_cnt = las = 1; }
  void add_edge(int u, int v) {
    edge[++edge_cnt] = v;
    nxt[edge_cnt] = head[u];
    head[u] = edge_cnt;
  }
  void insert(int c, int id) {
    int np = ++node_cnt, p = las;
    las = np;
    len[np] = len[p] + 1;
    ep[np] = id;
    while (p && !ch[p][c]) {
      ch[p][c] = np;
      p = fa[p];
    }
    if (!p)
      fa[np] = 1;
    else {
      int q = ch[p][c];
      if (len[q] == len[p] + 1)
        fa[np] = q;
      else {
        int nq = ++node_cnt;
        fa[nq] = fa[q];
        len[nq] = len[p] + 1;
        for (int i = 0; i < 26; i++) ch[nq][i] = ch[q][i];
        fa[q] = fa[np] = nq;
        while (p && ch[p][c] == q) {
          ch[p][c] = nq;
          p = fa[p];
        }
      }
    }
  }
  void dfs(int u) {
    for (int i = head[u]; i; i = nxt[i]) {
      int v = edge[i];
      dfs(v);
      rt[u] = tree.merge(rt[u], rt[v], 1, n);
    }
    if (ep[u]) tree.insert(rt[u], 1, n, ep[u]);
  }
  void build(char *ch) {
    for (int i = 1; i <= n; i++) insert(ch[i] - 'a', i);
    for (int i = 2; i <= node_cnt; i++) add_edge(fa[i], i);
    dfs(1);
  }
  void query(int l, int r, char *t) {
    int Len = strlen(t + 1), u = 1;
    t[Len + 1] = 'a' - 1;
    for (int i = 1; i <= Len + 1; i++) ans[i] = 0;
    for (int i = 1; i <= Len + 1; i++) {
      for (int j = t[i] + 1 - 'a'; j < 26; j++)
        if (ch[u][j]) {
          if (tree.query(rt[ch[u][j]], 1, n, l + i - 1, r)) {
            ans[i] = j + 'a';
            break;
          }
        }
      if (i == Len + 1) break;
      int c = t[i] - 'a';
      if (!ch[u][c]) break;
      u = ch[u][c];
      if (!tree.query(rt[u], 1, n, l + i - 1, r)) break;
    }
    for (int i = Len + 1; i >= 1; i--)
      if (ans[i]) {
        for (int j = 1; j < i; j++) printf("%c", t[j]);
        printf("%c\n", ans[i]);
        return;
      }
    printf("-1\n");
  }
} s;
int main() {
  scanf("%s", ch + 1);
  n = strlen(ch + 1);
  s.build(ch);
  scanf("%d", &q);
  int l, r;
  while (q--) {
    scanf("%d%d%s", &l, &r, t + 1);
    s.query(l, r, t);
  }
  return 0;
}
