#include <bits/stdc++.h>
using namespace std;
#pragma warning(disable : 4996)
int Slen = 100001;
const int SZ = 500010 * 21;
int seg_tree[SZ], L_ptr[SZ], R_ptr[SZ], Next = 1;
int add(int c, int l, int r, int pos) {
  if (l > pos || r < pos) return c;
  int ID = Next++;
  if (l == r) {
    seg_tree[ID] = seg_tree[c] + 1;
    return ID;
  }
  int mid = (l + r) >> 1;
  L_ptr[ID] = add(L_ptr[c], l, mid, pos);
  R_ptr[ID] = add(R_ptr[c], mid + 1, r, pos);
  seg_tree[ID] = seg_tree[L_ptr[ID]] + seg_tree[R_ptr[ID]];
  return ID;
}
int find_sum(int l_tree_c, int r_tree_c, int l, int r, int qry_l, int qry_r) {
  if (qry_l > r || qry_r < l) return 0;
  if (l >= qry_l && r <= qry_r) {
    return seg_tree[r_tree_c] - seg_tree[l_tree_c];
  }
  int mid = (l + r) >> 1;
  return find_sum(L_ptr[l_tree_c], L_ptr[r_tree_c], l, mid, qry_l, qry_r) +
         find_sum(R_ptr[l_tree_c], R_ptr[r_tree_c], mid + 1, r, qry_l, qry_r);
}
int find_first(int l_tree_c, int r_tree_c, int l, int r, int qry_l, int qry_r) {
  if (qry_l > r || qry_r < l || (seg_tree[r_tree_c] - seg_tree[l_tree_c]) == 0)
    return -1;
  if (l == r) {
    return l;
  }
  int mid = (l + r) >> 1;
  int val = find_first(L_ptr[l_tree_c], L_ptr[r_tree_c], l, mid, qry_l, qry_r);
  if (val == -1)
    return find_first(R_ptr[l_tree_c], R_ptr[r_tree_c], mid + 1, r, qry_l,
                      qry_r);
  return val;
}
char T[500010], S[500010];
int n;
int RA[500010], tempRA[500010];
int SA[500010], tempSA[500010];
int LCP[500010], Phi[500010], PLCP[500010];
int c[500010], cnt = 1;
void countingSort(int k) {
  int i, sum, maxi = max(300, n);
  memset(c, 0, sizeof c);
  for (i = 0; i < n; i++) c[i + k < n ? RA[i + k] : 0]++;
  for (i = sum = 0; i < maxi; i++) {
    int t = c[i];
    c[i] = sum;
    sum += t;
  }
  for (i = 0; i < n; i++)
    tempSA[c[SA[i] + k < n ? RA[SA[i] + k] : 0]++] = SA[i];
  for (i = 0; i < n; i++) SA[i] = tempSA[i];
}
void constructSA() {
  int i, k, r;
  for (i = 0; i < n; i++) RA[i] = T[i];
  for (i = 0; i < n; i++) SA[i] = i;
  for (k = 1; k < n; k <<= 1) {
    countingSort(k);
    countingSort(0);
    tempRA[SA[0]] = r = 0;
    for (i = 1; i < n; i++)
      tempRA[SA[i]] =
          (RA[SA[i]] == RA[SA[i - 1]] && RA[SA[i] + k] == RA[SA[i - 1] + k])
              ? r
              : ++r;
    for (i = 0; i < n; i++) RA[i] = tempRA[i];
    if (RA[SA[n - 1]] == n - 1) break;
  }
}
void computeLCP() {
  int i, L;
  Phi[SA[0]] = -1;
  for (i = 1; i < n; i++) Phi[SA[i]] = SA[i - 1];
  for (i = L = 0; i < n; i++) {
    if (Phi[i] == -1) {
      PLCP[i] = 0;
      continue;
    }
    while (T[i + L] == T[Phi[i] + L]) L++;
    PLCP[i] = L;
    L = max(L - 1, 0);
  }
  for (i = 0; i < n; i++) LCP[i] = PLCP[SA[i]];
}
struct node {
  int lf, sp, depth;
  map<char, node *> M;
  node *parent;
  node() : lf(0), depth(0), parent(NULL), sp(0) {}
} * rt;
node pool[500010 * 2 + 4];
int CNT = 0;
node &get_node() { return pool[CNT++]; }
void split(node *&n, int id, int lcp) {
  node *x = n->parent;
  node *y = &get_node();
  node *z = &get_node();
  x->M[T[n->sp + x->depth]] = y;
  y->depth = lcp;
  y->sp = id;
  y->M[T[lcp + id]] = z;
  y->M[T[n->sp + lcp]] = n;
  y->parent = x;
  n->parent = y;
  z->depth = ::n - id;
  z->sp = id;
  z->parent = y;
  n = z;
}
void add(node *&n, int id, int lcp) {
  if (lcp == 0) {
    node *y = &get_node();
    y->depth = ::n - id;
    y->sp = id;
    y->parent = rt;
    rt->M[T[id]] = y;
    n = y;
    return;
  }
  while (n->parent->depth > lcp) n = n->parent;
  if (n->parent->depth == lcp) {
    n = n->parent;
    node *y = &get_node();
    y->depth = ::n - id;
    y->sp = id;
    y->parent = n;
    n->M[T[id + lcp]] = y;
    n = y;
    return;
  }
  split(n, id, lcp);
}
vector<int> start_idx(1 + 500010 * 2), end_idx(500010), tree_id(500010 * 2 + 1);
void dfs(node *n) {
  n->lf = cnt++;
  start_idx[n->lf] = n->lf;
  if (!(n->M.size()))
    tree_id[n->lf] = add(tree_id[n->lf - 1], 0, Slen, n->sp);
  else
    tree_id[n->lf] = tree_id[n->lf - 1];
  for (auto &x : n->M) {
    dfs(x.second);
  }
  end_idx[n->lf] = cnt - 1;
}
void climb_up_for_greater(node *cr, int L, int R) {
  int match = cr->depth;
  while (true) {
    match = cr->depth;
    if (cr->M.upper_bound(S[match]) == cr->M.end()) {
      if (cr == rt) break;
      cr = cr->parent;
      continue;
    }
    auto it = cr->M.upper_bound(S[match]);
    int start, end;
    int left_valid = -1;
    while (it != cr->M.end() && left_valid == -1) {
      start = it->second->lf, end = it->second->lf;
      left_valid = find_first(tree_id[start_idx[start] - 1],
                              tree_id[end_idx[end]], 0, Slen, L, R - cr->depth);
      if (left_valid != -1) {
        break;
      }
      ++it;
    }
    if (left_valid == -1) {
      if (cr == rt) {
        break;
      }
      cr = cr->parent;
      continue;
    }
    for (int i = left_valid; i <= left_valid + match; i++) {
      putchar(T[i]);
    }
    putchar('\n');
    return;
  }
  printf("-1\n");
}
void query(int L, int R) {
  node *cr = rt;
  int match = 0;
  int Len = strlen(S);
  while (true) {
    if (cr->M.lower_bound(S[match]) == cr->M.end()) {
      climb_up_for_greater(cr, L, R);
      return;
    }
    auto it = cr->M.lower_bound(S[match]);
    int start, end;
    int left_valid = -1;
    while (it != cr->M.end() && left_valid == -1) {
      start = it->second->lf, end = it->second->lf;
      left_valid = find_first(tree_id[start_idx[start] - 1],
                              tree_id[end_idx[end]], 0, Slen, L, R - cr->depth);
      if (left_valid != -1) {
        cr = it->second;
        break;
      }
      ++it;
    }
    if (left_valid == -1) {
      climb_up_for_greater(cr, L, R);
      return;
    }
    start = left_valid + match;
    while (match < Len && match < cr->depth && start <= R &&
           T[start] == S[match])
      ++match, ++start;
    if (match == cr->depth) continue;
    if (start > R) {
      cr = cr->parent;
      climb_up_for_greater(cr, L, R);
      return;
    }
    if (match == Len || T[start] > S[match]) {
      for (int i = left_valid; i <= start; i++) putchar(T[i]);
      putchar('\n');
      return;
    }
    if (T[start] < S[match]) {
      cr = cr->parent;
      climb_up_for_greater(cr, L, R);
      return;
    }
  }
}
int main() {
  scanf("%s", T);
  n = strlen(T);
  T[n++] = '$';
  constructSA();
  computeLCP();
  node *ty;
  rt = &get_node();
  ty = rt;
  for (int i = 0; i < n; i++) {
    add(ty, SA[i], LCP[i]);
  }
  dfs(rt);
  int q;
  cin >> q;
  for (int i = 0; i < q; i++) {
    int L, R;
    scanf("%d%d%s", &L, &R, S);
    --L, --R;
    query(L, R);
  }
  return 0;
}
