#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
const int MAXS = 5e5 + 5;
vector<int> g[MAXN], qu[MAXS], f[MAXS];
struct Seg {
  int x, y;
  Seg() {}
  Seg(int a, int b) {
    x = a;
    y = b;
  }
  bool operator<(const Seg &a) const { return x == a.x ? y > a.y : x < a.x; }
} ans[MAXS], val[MAXN * 20];
int ch[MAXN * 20][2], rt[MAXN], askl[MAXS], askr[MAXS], sl[MAXS], sr[MAXS];
int cnt, m;
inline void fix(int &x, int l, int r, int pos) {
  if (!x) x = ++cnt;
  if (l == r) {
    val[x].x++;
    val[x].y = l;
    return;
  }
  int mid = l + r >> 1;
  if (pos <= mid)
    fix(ch[x][0], l, mid, pos);
  else
    fix(ch[x][1], mid + 1, r, pos);
  val[x] = max(val[ch[x][0]], val[ch[x][1]]);
}
inline int merge(int x, int y) {
  if (!x || !y) return x | y;
  if (!ch[x][0] && !ch[x][1]) {
    val[x].x += val[y].x;
    return x;
  }
  ch[x][0] = merge(ch[x][0], ch[y][0]);
  ch[x][1] = merge(ch[x][1], ch[y][1]);
  val[x] = max(val[ch[x][0]], val[ch[x][1]]);
  return x;
}
inline Seg query(int x, int l, int r, int ql, int qr) {
  if (!x) return (Seg){0, 0};
  if (ql <= l && r <= qr) return val[x];
  int mid = l + r >> 1;
  if (ql > mid) return query(ch[x][1], mid + 1, r, ql, qr);
  if (qr <= mid) return query(ch[x][0], l, mid, ql, qr);
  return max(query(ch[x][0], l, mid, ql, qr),
             query(ch[x][1], mid + 1, r, ql, qr));
}
void dfs(int x) {
  for (int i = 0; i < g[x].size(); i++) {
    int v = g[x][i];
    dfs(v);
    rt[x] = merge(rt[x], rt[v]);
  }
  for (int i = 0; i < qu[x].size(); i++) {
    int now = qu[x][i];
    ans[now] = query(rt[x], 1, m, askl[now], askr[now]);
  }
}
int tot = 1, last = 1, ss, fa[MAXN][21], pos[MAXN], len[MAXN], son[MAXN][26];
inline void ins(int c, int id) {
  int p = last;
  if (son[p][c]) {
    int q = son[p][c];
    if (len[q] == len[p] + 1)
      last = q;
    else {
      int nq = ++tot;
      last = tot;
      len[nq] = len[p] + 1;
      fa[nq][0] = fa[q][0];
      fa[q][0] = nq;
      memcpy(son[nq], son[q], sizeof(son[q]));
      while (p && son[p][c] == q) son[p][c] = nq, p = fa[p][0];
    }
    return;
  }
  int np = ++tot;
  last = np;
  len[np] = len[p] + 1;
  while (p && !son[p][c]) son[p][c] = np, p = fa[p][0];
  if (!p)
    fa[np][0] = 1;
  else {
    int q = son[p][c];
    if (len[q] == len[p] + 1)
      fa[np][0] = q;
    else {
      int nq = ++tot;
      len[nq] = len[p] + 1;
      memcpy(son[nq], son[q], sizeof(son[q]));
      fa[nq][0] = fa[q][0];
      fa[q][0] = fa[np][0] = nq;
      while (p && son[p][c] == q) son[p][c] = nq, p = fa[p][0];
    }
  }
}
char s[MAXS], t[MAXS];
int Len, q;
int main() {
  scanf("%s", s + 1);
  Len = strlen(s + 1);
  scanf("%d", &m);
  for (int i = 1, l; i <= m; i++) {
    scanf("%s", t + 1);
    l = strlen(t + 1);
    last = 1;
    for (int j = 1; j <= l; j++) ins(t[j] - 'a', i), fix(rt[last], 1, m, i);
  }
  scanf("%d", &q);
  for (int i = 1; i <= q; i++)
    scanf("%d%d%d%d", &askl[i], &askr[i], &sl[i], &sr[i]),
        f[sr[i]].push_back(i);
  for (int i = 2; i <= tot; i++) g[fa[i][0]].push_back(i);
  for (int i = 1; (1 << i) <= tot; i++)
    for (int j = 1; j <= tot; j++) fa[j][i] = fa[fa[j][i - 1]][i - 1];
  int now = 1, dep = 0;
  for (int i = 1; i <= Len; i++) {
    while (now && !son[now][s[i] - 'a']) now = fa[now][0], dep = len[now];
    if (!now) {
      now = 1;
      dep = 0;
      continue;
    }
    now = son[now][s[i] - 'a'];
    dep++;
    for (int j = 0; j < f[i].size(); j++) {
      int v = f[i][j], x = now;
      if (dep < sr[v] - sl[v] + 1) continue;
      for (int k = 18; k >= 0; k--)
        if (fa[x][k] && len[fa[x][k]] >= sr[v] - sl[v] + 1) x = fa[x][k];
      qu[x].push_back(v);
    }
  }
  dfs(1);
  for (int i = 1; i <= q; i++)
    if (!ans[i].x) ans[i].y = askl[i];
  for (int i = 1; i <= q; i++) printf("%d %d\n", ans[i].y, ans[i].x);
  return 0;
}
