#include <bits/stdc++.h>
using namespace std;
const int N = 100010, M = 1000010;
char ss[N], s[M];
int n, m, Q, l1, r1, l2, r2, nd = 1, cnt, pos[M], L[M];
int mx[M], q[M], fa[M], c[M], son[M][27], rt[M], f[M][22];
struct P {
  int x, id;
};
struct Tr {
  int lc, rc;
  P p;
} v[N * 30];
bool operator<(const P &a, const P &b) {
  return a.x == b.x ? a.id > b.id : a.x < b.x;
}
int work(int p, int c) {
  int nq = ++nd, q = son[p][c];
  mx[nq] = mx[p] + 1;
  fa[nq] = fa[q];
  fa[q] = nq;
  memcpy(son[nq], son[q], sizeof(son[q]));
  while (p && son[p][c] == q) son[p][c] = nq, p = fa[p];
  return nq;
}
int ext(int p, int c) {
  if (son[p][c]) {
    int q = son[p][c];
    if (mx[q] == mx[p] + 1)
      return q;
    else
      return work(p, c);
  } else {
    int np = ++nd;
    mx[np] = mx[p] + 1;
    while (p && !son[p][c]) son[p][c] = np, p = fa[p];
    if (!p) {
      fa[np] = 1;
      return np;
    }
    int q = son[p][c];
    if (mx[q] == mx[p] + 1)
      fa[np] = q;
    else
      fa[np] = work(p, c);
    return np;
  }
}
void upd(int x) { v[x].p = max(v[v[x].lc].p, v[v[x].rc].p); }
int merge(int x, int y, int L, int R) {
  if (!x || !y) return x | y;
  int k = ++cnt;
  if (L == R) {
    v[k].p = (P){v[x].p.x + v[y].p.x, L};
    return k;
  }
  int mid = (L + R) >> 1;
  v[k].lc = merge(v[x].lc, v[y].lc, L, mid);
  v[k].rc = merge(v[x].rc, v[y].rc, mid + 1, R);
  upd(k);
  return k;
}
void mdf(int &x, int L, int R, int k) {
  if (!x) x = ++cnt;
  if (L == R) {
    v[x].p = (P){v[x].p.x + 1, k};
    return;
  }
  int mid = (L + R) >> 1;
  if (k <= mid)
    mdf(v[x].lc, L, mid, k);
  else
    mdf(v[x].rc, mid + 1, R, k);
  upd(x);
}
P que(int x, int L, int R, int l, int r) {
  if (!x) return (P){0, 0};
  if (L == l && r == R) return v[x].p;
  int mid = (L + R) >> 1;
  if (r <= mid) return que(v[x].lc, L, mid, l, r);
  if (l > mid) return que(v[x].rc, mid + 1, R, l, r);
  return max(que(v[x].lc, L, mid, l, mid),
             que(v[x].rc, mid + 1, R, mid + 1, r));
}
int get(int x, int k) {
  for (int i = 20; ~i; i--)
    if (mx[f[x][i]] >= k) x = f[x][i];
  return x;
}
int main() {
  scanf("%s%d", s + 1, &m);
  n = strlen(s + 1);
  for (int i = (1); i <= (m); i++) {
    scanf("%s", ss + 1);
    int len = strlen(ss + 1), x = 1;
    for (int j = (1); j <= (len); j++)
      x = ext(x, ss[j] - 'a'), mdf(rt[x], 1, m, i);
  }
  int x = 1, l = 0;
  for (int i = (1); i <= (n); i++) {
    int c = s[i] - 'a';
    while (x && !son[x][c]) x = fa[x], l = mx[x];
    if (son[x][c])
      L[i] = ++l, x = son[x][c], pos[i] = x;
    else
      x = 1, L[i] = l = 0;
  }
  int t = 0;
  for (int i = (1); i <= (nd); i++) c[mx[i]]++, t = max(t, mx[i]);
  for (int i = (1); i <= (t); i++) c[i] += c[i - 1];
  for (int i = nd; i; i--) q[c[mx[i]]--] = i;
  for (int i = nd; i; i--) rt[fa[q[i]]] = merge(rt[fa[q[i]]], rt[q[i]], 1, m);
  rt[1] = 0;
  for (int i = (1); i <= (nd); i++) f[i][0] = fa[i];
  for (int j = (1); j <= (20); j++)
    for (int i = (1); i <= (nd); i++) f[i][j] = f[f[i][j - 1]][j - 1];
  for (scanf("%d", &Q); Q--;) {
    scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
    if (L[r2] < r2 - l2 + 1) {
      printf("%d 0\n", l1);
      continue;
    }
    P t = que(rt[get(pos[r2], r2 - l2 + 1)], 1, m, l1, r1);
    if (t.x)
      printf("%d %d\n", t.id, t.x);
    else
      printf("%d 0\n", l1);
  }
  return 0;
}
