#include <bits/stdc++.h>
using namespace std;
inline long long rd() {
  long long x = 0, f = 1;
  char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-') f = -1;
  for (; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
  return x * f;
}
void write(long long x) {
  if (x < 0) x = -x, putchar('-');
  if (x >= 10) write(x / 10);
  putchar(x % 10 + '0');
}
void writeln(long long x) {
  write(x);
  puts("");
}
const int maxn = 2e5 + 233;
namespace SegmentTree {
const int maxm = maxn * 60;
int lc[maxm], rc[maxm], T[maxm], tot = 0;
inline void insert(int &o, int l, int r, int x, int v) {
  if (!o) o = ++tot, T[o] = 0;
  T[o] |= v;
  if (l == r) return;
  int mid = (l + r) >> 1;
  if (x <= mid)
    insert(lc[o], l, mid, x, v);
  else
    insert(rc[o], mid + 1, r, x, v);
}
inline int query(int o, int l, int r, int x, int y) {
  if (!o) return 0;
  if (l == x && r == y) return T[o];
  int mid = (l + r) >> 1;
  if (y <= mid)
    return query(lc[o], l, mid, x, y);
  else if (mid + 1 <= x)
    return query(rc[o], mid + 1, r, x, y);
  else
    return query(lc[o], l, mid, x, mid) | query(rc[o], mid + 1, r, mid + 1, y);
}
inline int merge(int x, int y) {
  if (!x || !y) return x + y;
  int z = ++tot;
  T[z] = T[x] | T[y];
  lc[z] = merge(lc[x], lc[y]);
  rc[z] = merge(rc[x], rc[y]);
  return z;
}
}  // namespace SegmentTree
using SegmentTree::insert;
using SegmentTree::merge;
using SegmentTree::query;
int root[maxn * 2], n;
struct SAM {
  static const int maxm = maxn * 2;
  struct node {
    int link, nxt[26], max;
  } T[maxm];
  int tot, start, last;
  SAM() {
    tot = 0;
    start = last = newnode(0);
  }
  int newnode(int x) {
    ++tot;
    T[tot].link = 0;
    memset(T[tot].nxt, 0, sizeof(T[tot].nxt));
    T[tot].max = x;
    return tot;
  }
  int tpos[maxm], vpos[maxm];
  void extend(char c, int flag) {
    int u = newnode(T[last].max + 1), v = last;
    tpos[v] = flag;
    vpos[v] = c;
    for (; v && T[v].nxt[c] == 0; v = T[v].link) {
      T[v].nxt[c] = u;
    }
    if (!v) {
      T[u].link = start;
    } else if (T[v].max + 1 == T[T[v].nxt[c]].max) {
      T[u].link = T[v].nxt[c];
    } else {
      int n = newnode(T[v].max + 1), o = T[v].nxt[c];
      for (register int i = (0); i < int(26); ++i) T[n].nxt[i] = T[o].nxt[i];
      T[n].link = T[o].link;
      T[o].link = T[u].link = n;
      for (; v && T[v].nxt[c] == o; v = T[v].link) T[v].nxt[c] = n;
    }
    last = u;
  }
  vector<int> edge[maxm];
  void dfs(int u) {
    for (auto v : edge[u]) {
      dfs(v);
      root[u] = merge(root[u], root[v]);
    }
  }
  void init() {
    for (register int i = (1); i <= int(tot); ++i) root[i] = 0;
    for (register int i = (1); i <= int(tot); ++i)
      if (tpos[i]) {
        insert(root[i], 1, n, tpos[i], 1 << vpos[i]);
      }
    for (register int i = (2); i <= int(tot); ++i) {
      edge[T[i].link].push_back(i);
    }
    dfs(1);
  }
} sam;
char S[maxn], T[maxn];
int main() {
  scanf("%s", S + 1);
  n = strlen(S + 1);
  for (register int i = (1); i <= int(n); ++i) sam.extend(S[i] - 'a', i);
  sam.init();
  int Case = rd();
  while (Case--) {
    int l = rd(), r = rd();
    scanf("%s", T + 1);
    T[strlen(T + 1) + 2] = 0;
    T[strlen(T + 1) + 1] = 'a' - 1;
    int p1 = -1, p2 = -1;
    int u = 1;
    for (int i = 1; T[i] && u; i++) {
      int t = query(root[u], 1, n, l + i - 1, r), tmp = T[i] - 'a' + 1;
      for (register int j = (tmp); j < int(26); ++j)
        if (t >> j & 1) {
          p1 = i, p2 = j;
          break;
        }
      if (T[i] >= 'a') u = sam.T[u].nxt[T[i] - 'a'];
    }
    if (p1 == -1) {
      puts("-1");
    } else {
      for (register int i = (1); i < int(p1); ++i) putchar(T[i]);
      putchar('a' + p2);
      puts("");
    }
  }
  return 0;
}
