#include <bits/stdc++.h>
using namespace std;
const int N = 100050;
const int M = 500050;
inline int rd() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = 0;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 3) + (x << 1) + (ch ^ 48);
    ch = getchar();
  }
  return f ? x : -x;
}
int ch[N][26], pre[N], len[N];
int n, m, cnt, sz, q, tot, las;
char S[M], T[N];
int fir[N], rt[N], fa[N][18], lg[N];
int sl[M], sr[M], pl[M], pr[M];
vector<int> q1[M], q2[M];
vector<int>::iterator it;
struct Node {
  int x, y;
  Node() {}
  Node(int a, int b) { x = a, y = b; }
  bool operator<(const Node &a) const {
    return (x == a.x) ? (y > a.y) : (x < a.x);
  }
} ans[M];
struct sgt {
  int lc, rc;
  Node v;
} s[N * 20];
struct Edge {
  int nxt, to;
} e[N << 1];
inline void ins(int c) {
  int p = las;
  if (ch[p][c]) {
    int q = ch[p][c];
    if (len[q] == len[p] + 1)
      las = q;
    else {
      int nq = ++tot;
      las = tot;
      len[nq] = len[p] + 1;
      pre[nq] = pre[q];
      pre[q] = nq;
      memcpy(ch[nq], ch[q], sizeof ch[q]);
      for (; p && ch[p][c] == q; p = pre[p]) ch[p][c] = nq;
    }
  } else {
    int np = ++tot;
    las = np;
    len[np] = len[p] + 1;
    for (; p && !ch[p][c]; p = pre[p]) ch[p][c] = np;
    if (!p)
      pre[np] = 1;
    else {
      int q = ch[p][c];
      if (len[q] == len[p] + 1)
        pre[np] = q;
      else {
        int nq = ++tot;
        len[nq] = len[p] + 1;
        pre[nq] = pre[q];
        pre[q] = pre[np] = nq;
        memcpy(ch[nq], ch[q], sizeof ch[q]);
        for (; p && ch[p][c] == q; p = pre[p]) ch[p][c] = nq;
      }
    }
  }
}
inline void add(int from, int to) {
  e[++cnt].nxt = fir[from];
  fir[from] = cnt;
  e[cnt].to = to;
}
inline void update(int &x, int l, int r, int to) {
  if (!x) x = ++sz;
  if (l == r) {
    s[x].v.x++;
    s[x].v.y = l;
    return;
  }
  int mid = (l + r) / 2;
  if (to <= mid)
    update(s[x].lc, l, mid, to);
  else
    update(s[x].rc, mid + 1, r, to);
  s[x].v = max(s[s[x].lc].v, s[s[x].rc].v);
}
inline int merge(int x, int y) {
  if (!x || !y) return x + y;
  if (!s[x].lc && !s[x].rc) {
    s[x].v.x += s[y].v.x;
    return x;
  }
  s[x].lc = merge(s[x].lc, s[y].lc);
  s[x].rc = merge(s[x].rc, s[y].rc);
  s[x].v = max(s[s[x].lc].v, s[s[x].rc].v);
  return x;
}
inline Node query(int x, int l, int r, int nl, int nr) {
  if (nl <= l && nr >= r) return s[x].v;
  int mid = (l + r) / 2;
  if (nr <= mid)
    return query(s[x].lc, l, mid, nl, nr);
  else if (nl > mid)
    return query(s[x].rc, mid + 1, r, nl, nr);
  else
    return max(query(s[x].lc, l, mid, nl, mid),
               query(s[x].rc, mid + 1, r, mid + 1, nr));
}
inline void dfs(int x) {
  for (int i = fir[x]; i; i = e[i].nxt) {
    int y = e[i].to;
    dfs(y);
    rt[x] = merge(rt[x], rt[y]);
  }
  for (it = q2[x].begin(); it != q2[x].end(); it++) {
    int a = *it;
    ans[a] = query(rt[x], 1, m, pl[a], pr[a]);
  }
}
int main() {
  scanf("%s", S);
  n = strlen(S);
  m = rd();
  tot = 1;
  int a, b, u, dep;
  for (int i = 1; i <= m; i++) {
    scanf("%s", T);
    a = strlen(T);
    las = 1;
    for (int j = 0; j < a; j++) ins(T[j] - 'a'), update(rt[las], 1, m, i);
  }
  q = rd();
  for (int i = 1; i <= q; i++) {
    pl[i] = rd();
    pr[i] = rd();
    sl[i] = rd() - 1;
    sr[i] = rd() - 1;
    q1[sr[i]].push_back(i);
  }
  for (int i = 2; i <= tot; i++) {
    add(pre[i], i);
    fa[i][0] = pre[i];
    lg[i] = lg[i >> 1] + 1;
  }
  for (int j = 1; (1 << j) <= tot; j++) {
    for (int i = 1; i <= tot; i++) {
      fa[i][j] = fa[fa[i][j - 1]][j - 1];
    }
  }
  u = 1, dep = 0;
  for (int i = 0; i < n; i++) {
    while (u && !ch[u][S[i] - 'a']) u = pre[u], dep = len[u];
    if (!u) {
      u = 1, dep = 0;
      continue;
    }
    u = ch[u][S[i] - 'a'], dep++;
    for (it = q1[i].begin(); it != q1[i].end(); it++) {
      a = *it, b = u;
      if (dep < sr[a] - sl[a] + 1) continue;
      for (int j = lg[len[u] + 1]; j >= 0; j--) {
        if (len[fa[b][j]] >= sr[a] - sl[a] + 1) b = fa[b][j];
      }
      q2[b].push_back(a);
    }
  }
  dfs(1);
  for (int i = 1; i <= q; i++) {
    if (!ans[i].x) ans[i].y = pl[i];
    printf("%d %d\n", ans[i].y, ans[i].x);
  }
  return 0;
}
