#include <bits/stdc++.h>
using namespace std;
const int N = 500010, M = 50010;
struct edge {
  int to, ne;
} e[M << 1];
struct ask {
  int l, r, pl, pr, id;
} a[N];
struct data {
  int x, id;
  data() {}
  data(int x, int id) : x(x), id(id) {}
} ans[N];
struct node {
  int l, r;
  data x;
} tr[(M << 1) * 40];
char s[N], ss[M];
int n, m, q, cnt = 1, lst = 1, cntt = 0, tot = 0;
int l[M << 1], fa[M << 1], ch[M << 1][30], rt[M << 1], h[M << 1], g[30][M << 1];
inline data update(data x, data y) {
  if (x.x >= y.x)
    return x;
  else
    return y;
}
inline int merge(int nd, int nod, int l, int r) {
  if (nod == 0) return nd;
  if (nd == 0) nd = ++cntt;
  if (l == r) {
    tr[nd].x.x += tr[nod].x.x;
    tr[nd].x.id = l;
    return nd;
  }
  int mid = (l + r) >> 1;
  tr[nd].l = merge(tr[nd].l, tr[nod].l, l, mid);
  tr[nd].r = merge(tr[nd].r, tr[nod].r, mid + 1, r);
  tr[nd].x = update(tr[tr[nd].l].x, tr[tr[nd].r].x);
  return nd;
}
inline int change(int nd, int l, int r, int x, int y) {
  if (nd == 0) nd = ++cntt;
  if (l == r) {
    tr[nd].x.x += y;
    tr[nd].x.id = l;
    return nd;
  }
  int mid = (l + r) >> 1;
  if (x <= mid)
    tr[nd].l = change(tr[nd].l, l, mid, x, y);
  else
    tr[nd].r = change(tr[nd].r, mid + 1, r, x, y);
  tr[nd].x = update(tr[tr[nd].l].x, tr[tr[nd].r].x);
  return nd;
}
inline data find(int nd, int l, int r, int x, int y) {
  if (nd == 0) {
    return data(0, 0);
  }
  if (l > y || r < x) return data(0, 0);
  if (l >= x && r <= y) {
    return tr[nd].x;
  }
  int mid = (l + r) >> 1;
  data u = find(tr[nd].l, l, mid, x, y);
  data v = find(tr[nd].r, mid + 1, r, x, y);
  return update(u, v);
}
inline void ins(int x, int id) {
  int p = ch[lst][x];
  if (p && l[fa[p]] + 1 == l[p]) {
    lst = p;
    rt[p] = change(rt[p], 1, m, id, 1);
    return;
  }
  int now = ++cnt, f = lst;
  l[now] = l[lst] + 1, lst = now;
  rt[now] = change(rt[now], 1, m, id, 1);
  while (f && ch[f][x] == 0) {
    ch[f][x] = now;
    f = fa[f];
  }
  if (f == 0) {
    fa[now] = 1;
    return;
  }
  int to = ch[f][x];
  if (l[f] + 1 == l[to])
    fa[now] = to;
  else {
    int nd = ++cnt;
    l[nd] = l[f] + 1;
    memcpy(ch[nd], ch[to], sizeof ch[to]);
    fa[nd] = fa[to], fa[to] = nd, fa[now] = nd;
    while (ch[f][x] == to) {
      ch[f][x] = nd;
      f = fa[f];
    }
  }
  return;
}
inline bool cmp(ask x, ask y) { return x.pr < y.pr; }
inline void add(int x, int y) {
  e[++tot].to = y;
  e[tot].ne = h[x];
  h[x] = tot;
  return;
}
inline void dfs(int x) {
  for (int k = h[x]; k; k = e[k].ne) {
    dfs(e[k].to);
    rt[x] = merge(rt[x], rt[e[k].to], 1, m);
  }
  return;
}
inline int get_nd(int nd, int len) {
  for (int k = 20; k >= 0; k--) {
    int to = g[k][nd];
    if (l[to] >= len) nd = to;
  }
  return nd;
}
int main() {
  scanf("%s", s + 1);
  n = strlen(s + 1);
  scanf("%d", &m);
  for (int k = 1; k <= m; k++) {
    lst = 1;
    scanf("%s", ss + 1);
    int len = strlen(ss + 1);
    for (int i = 1; i <= len; i++) ins(ss[i] - 'a', k);
  }
  scanf("%d", &q);
  for (int k = 1; k <= q; k++) {
    scanf("%d%d%d%d", &a[k].l, &a[k].r, &a[k].pl, &a[k].pr);
    a[k].id = k;
  }
  for (int k = 2; k <= cnt; k++) add(fa[k], k);
  dfs(1);
  for (int k = 1; k <= cnt; k++) g[0][k] = fa[k];
  for (int k = 1; k <= 20; k++)
    for (int i = 1; i <= cnt; i++) g[k][i] = g[k - 1][g[k - 1][i]];
  sort(a + 1, a + 1 + q, cmp);
  int now = 1, u = 1, len = 0;
  for (int k = 1; k <= n; k++) {
    int x = s[k] - 'a';
    while (now > 1 && ch[now][x] == 0) now = fa[now], len = l[now];
    if (ch[now][x]) now = ch[now][x], len++;
    while (a[u].pr == k) {
      if (len >= a[u].pr - a[u].pl + 1) {
        int nd = get_nd(now, a[u].pr - a[u].pl + 1);
        ans[a[u].id] = find(rt[nd], 1, m, a[u].l, a[u].r);
        if (ans[a[u].id].x == 0) ans[a[u].id].id = a[u].l;
      } else
        ans[a[u].id] = data(0, a[u].l);
      u++;
    }
  }
  for (int k = 1; k <= q; k++) printf("%d %d\n", ans[k].id, ans[k].x);
  return 0;
}
