#include <bits/stdc++.h>
using namespace std;
const int LEN = 600005 * 3;
int r[LEN], sa[LEN];
int wa[LEN], wb[LEN], wv[LEN], ss[LEN];
int c0(int *r, int a, int b) {
  return r[a] == r[b] && r[a + 1] == r[b + 1] && r[a + 2] == r[b + 2];
}
int c12(int k, int *r, int a, int b) {
  if (k == 2) return r[a] < r[b] || r[a] == r[b] && c12(1, r, a + 1, b + 1);
  return r[a] < r[b] || r[a] == r[b] && wv[a + 1] < wv[b + 1];
}
void sort(int *r, int *a, int *b, int n, int m) {
  for (int i = 0; i < n; i++) wv[i] = r[a[i]];
  for (int i = 0; i < m; i++) ss[i] = 0;
  for (int i = 0; i < n; i++) ss[wv[i]]++;
  for (int i = 1; i < m; i++) ss[i] += ss[i - 1];
  for (int i = n - 1; i >= 0; i--) b[--ss[wv[i]]] = a[i];
}
void DC3(int *r, int *sa, int n, int m) {
  int i, j, p;
  int *san = sa + n, *rn = r + n;
  int ta = 0, tb = (n + 1) / 3, tbc = 0;
  r[n] = r[n + 1] = 0;
  for (i = 0; i < n; i++)
    if (i % 3 != 0) wa[tbc++] = i;
  sort(r + 2, wa, wb, tbc, m);
  sort(r + 1, wb, wa, tbc, m);
  sort(r, wa, wb, tbc, m);
  for (p = 1, rn[((wb[0]) / 3 + ((wb[0]) % 3 == 1 ? 0 : tb))] = 0, i = 1;
       i < tbc; i++)
    rn[((wb[i]) / 3 + ((wb[i]) % 3 == 1 ? 0 : tb))] =
        c0(r, wb[i - 1], wb[i]) ? p - 1 : p++;
  if (p < tbc)
    DC3(rn, san, tbc, p);
  else
    for (i = 0; i < tbc; i++) san[rn[i]] = i;
  for (i = 0; i < tbc; i++)
    if (san[i] < tb) wb[ta++] = san[i] * 3;
  if (n % 3 == 1) wb[ta++] = n - 1;
  sort(r, wb, wa, ta, m);
  for (i = 0; i < tbc; i++)
    wv[wb[i] = ((san[i]) < tb ? (san[i]) * 3 + 1 : ((san[i]) - tb) * 3 + 2)] =
        i;
  for (i = 0, j = 0, p = 0; i < ta && j < tbc; p++)
    sa[p] = c12(wb[j] % 3, r, wa[i], wb[j]) ? wa[i++] : wb[j++];
  for (; i < ta; p++) sa[p] = wa[i++];
  for (; j < tbc; p++) sa[p] = wb[j++];
}
int rnk[600005], lcp[600005];
void calc_LCP(int *r, int *sa, int n) {
  lcp[0] = 0;
  for (int i = 0; i < n; i++) rnk[sa[i]] = i;
  for (int h = 0, i = 0; i < n; i++)
    if (rnk[i] > 0) {
      int j = sa[rnk[i] - 1];
      while (r[i + h] == r[j + h]) h++;
      lcp[rnk[i]] = h;
      if (h > 0) h--;
    }
}
char s[600005];
int pos[600005];
int a[600005], cnt[600005];
int lo[21][600005];
int hi[21][600005];
void init_RMQ(int n) {
  for (int i = 1; i <= n; i++) lo[0][i] = lcp[i];
  for (int i = 1; i < 21; i++) {
    for (int j = 1; j <= n; j++) {
      int k = j - (1 << (i - 1));
      if (k <= 0)
        lo[i][j] = 0;
      else
        lo[i][j] = min(lo[i - 1][j], lo[i - 1][k]);
    }
  }
  for (int i = 1; i <= n; i++) hi[0][i] = lcp[i + 1];
  for (int i = 1; i < 21; i++) {
    for (int j = 1; j <= n; j++) {
      int k = j + (1 << (i - 1));
      if (k > n)
        hi[i][j] = 0;
      else
        hi[i][j] = min(hi[i - 1][j], hi[i - 1][k]);
    }
  }
}
struct query {
  int L, R, pL, pR, id;
  query(int L = 0, int R = 0, int pL = 0, int pR = 0, int id = 0)
      : L(L), R(R), pL(pL), pR(pR), id(id) {}
  bool operator<(const query &q) const {
    int i = (pL + 250 - 1) / 250, j = (q.pL + 250 - 1) / 250;
    if (i != j) return i < j;
    return pR < q.pR;
  }
} q[600005];
struct RLT {
  int x, y;
  RLT(int x = 0, int y = 0) : x(x), y(y) {}
  bool operator<(const RLT &p) const { return y != p.y ? y > p.y : x < p.x; }
} rlt[600005];
template <class T>
void chkmin(T &a, T b) {
  if (b < a) a = b;
}
class RMQ_Tree {
 private:
  int n;
  RLT Min[600005 << 1];

 public:
  void build(int m) {
    Min[n = m] = RLT(n, 0);
    for (int i = 1; i <= n; i++) Min[i + n] = RLT(i, 0);
    for (int i = n - 1; i; i--) Min[i] = min(Min[i << 1], Min[i << 1 | 1]);
  }
  void modify(int p, RLT v) {
    Min[p += n] = v;
    for (; p > 1; p >>= 1) Min[p >> 1] = min(Min[p], Min[p ^ 1]);
  }
  RLT queryMin(int L, int R) {
    RLT rlt = RLT(-1, -1);
    for (L += n, R += n; L <= R; L = (L + 1) >> 1, R = (R - 1) >> 1) {
      if (L & 1) chkmin(rlt, Min[L]);
      if (!(R & 1)) chkmin(rlt, Min[R]);
    }
    return rlt;
  }
} T;
int inv[600005];
void poke(int u) {
  int id = pos[sa[a[u]]];
  cnt[id] += inv[u] ? -1 : 1;
  inv[u] ^= 1;
  T.modify(id, RLT(id, cnt[id]));
}
int main() {
  scanf("%s", s);
  int len = 0, n, m;
  int sn = strlen(s);
  for (int i = (0); i < (sn); i++) r[len++] = s[i];
  r[len++] = 256;
  scanf("%d\n", &n);
  for (int i = (1); i < (n + 1); i++) {
    scanf("%s", s);
    for (int j = 0; s[j]; j++) pos[len] = i, r[len++] = s[j];
    r[len++] = 256 + i;
  }
  DC3(r, sa, len + 1, n + 266);
  calc_LCP(r, sa, len + 1);
  init_RMQ(len);
  int tot = 0;
  for (int i = (0); i < (len); i++)
    if (pos[sa[i]]) a[++tot] = i;
  scanf("%d", &m);
  for (int i = (1); i < (m + 1); i++) {
    int L, R, x, y;
    scanf("%d%d%d%d", &L, &R, &x, &y);
    int p = rnk[x - 1], pL = p, pR = p;
    for (int j = 21 - 1; j >= 0; j--) {
      if (lo[j][pL] >= y - x + 1) pL -= (1 << j);
      if (hi[j][pR] >= y - x + 1) pR += (1 << j);
    }
    pL = lower_bound(a + 1, a + tot + 1, pL) - a;
    pR = upper_bound(a + 1, a + tot + 1, pR) - a - 1;
    q[i] = query(L, R, pL, pR, i);
  }
  sort(q + 1, q + m + 1);
  T.build(n);
  int L = 1, R = 0;
  for (int i = (1); i < (m + 1); i++) {
    while (R < q[i].pR) poke(++R);
    while (L > q[i].pL) poke(--L);
    while (R > q[i].pR) poke(R--);
    while (L < q[i].pL) poke(L++);
    rlt[q[i].id] = T.queryMin(q[i].L, q[i].R);
  }
  for (int i = (1); i < (m + 1); i++) printf("%d %d\n", rlt[i].x, rlt[i].y);
  return 0;
}
