#include <bits/stdc++.h>
int rd() {
  int k = 0;
  char c = getchar();
  while (c > '9' || c < '0') c = getchar();
  while (c >= '0' && c <= '9') k = k * 10 + c - 48, c = getchar();
  return k;
}
const int N = 500001, M = 100001, G = 2000001;
struct T {
  int f, s[26], len;
} t[M];
struct E {
  int v, nxt;
} e[M];
struct D {
  int w, p;
} d[G], p[N];
D operator+(D x, D y) { return x.w >= y.w ? x : y; }
int n, m, pn = 1, en, tn, lst, head[M], rt[M], f[M][18], ls[G], rs[G];
char c[N], s[M];
void Update(int& x, int l, int r, int w) {
  if (!x) x = ++tn;
  if (l == r) {
    d[x].p = l, ++d[x].w;
    return;
  }
  int p = l + r >> 1;
  if (w <= p)
    Update(ls[x], l, p, w);
  else
    Update(rs[x], p + 1, r, w);
  d[x] = d[ls[x]] + d[rs[x]];
}
int Merge(int x, int y, int l, int r) {
  if (!x || !y) return x | y;
  int z = ++tn;
  if (l == r) {
    d[z] = d[x], d[z].w += d[y].w;
    return z;
  }
  int p = l + r >> 1;
  ls[z] = Merge(ls[x], ls[y], l, p), rs[z] = Merge(rs[x], rs[y], p + 1, r),
  d[z] = d[ls[z]] + d[rs[z]];
  return z;
}
D Query(int x, int l, int r, int L, int R) {
  if (!x) return {0, 0};
  if (L <= l && r <= R) return d[x];
  int p = l + r >> 1;
  D s = {0, 0};
  if (L <= p) s = s + Query(ls[x], l, p, L, R);
  if (p < R) s = s + Query(rs[x], p + 1, r, L, R);
  return s;
}
void add(int u, int v) { e[++en].v = v, e[en].nxt = head[u], head[u] = en; }
void dfs(int u) {
  for (int i = 1; f[u][i - 1]; ++i) f[u][i] = f[f[u][i - 1]][i - 1];
  for (int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].v;
    dfs(v), rt[u] = Merge(rt[u], rt[v], 1, n);
  }
}
int Insert(int c, int w) {
  int p = lst;
  if (t[p].s[c] && t[t[p].s[c]].len == t[p].len + 1) {
    Update(rt[t[p].s[c]], 1, n, w);
    return t[p].s[c];
  }
  int np = ++pn;
  t[np].len = t[p].len + 1;
  Update(rt[np], 1, n, w);
  for (; p && !t[p].s[c]; p = t[p].f) t[p].s[c] = np;
  if (!p) {
    t[np].f = 1;
    return np;
  }
  int q = t[p].s[c];
  if (t[q].len == t[p].len + 1) {
    t[np].f = q;
    return np;
  }
  int nq = ++pn;
  t[nq] = t[q], t[nq].len = t[p].len + 1, t[np].f = t[q].f = nq;
  for (; p && t[p].s[c] == q; p = t[p].f) t[p].s[c] = nq;
  return p == lst ? nq : np;
}
int main() {
  scanf("%s", c + 1), n = rd();
  for (int i = 1; i <= n; ++i) {
    scanf("%s", s), lst = 1;
    for (m = 0; s[m]; ++m) lst = Insert(s[m] - 'a', i);
  }
  for (int i = 2; i <= pn; ++i) add(t[i].f, i), f[i][0] = t[i].f;
  dfs(1), m = 1;
  for (int u = 1, l = 0, ch; c[m]; ++m) {
    ch = c[m] - 'a';
    if (t[u].s[ch])
      u = t[u].s[ch], ++l;
    else {
      while (u && !t[u].s[ch]) u = t[u].f;
      if (!u)
        u = 1, l = 0;
      else
        l = t[u].len + 1, u = t[u].s[ch];
    }
    p[m] = {l, u};
  }
  m = rd();
  while (m--) {
    int a = rd(), b = rd(), l = rd(), r = rd(), len = r - l + 1, u = p[r].p;
    if (len > p[r].w) {
      printf("%d 0\n", a);
      continue;
    }
    for (int i = 17; i >= 0; --i)
      if (t[f[u][i]].len >= len) u = f[u][i];
    D s = Query(rt[u], 1, n, a, b);
    printf("%d %d\n", s.w ? s.p : a, s.w);
  }
  return 0;
}
