#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 7;
const int maxm = 1e5 + 7;
struct Que {
  int l, r, rt, id;
};
struct Data {
  int sum;
  int id;
  bool operator<(const Data& a) const {
    return (sum == a.sum) ? (id < a.id) : (sum > a.sum);
  }
};
struct Edge {
  int to, last;
} E[maxm];
vector<Que> Q[maxm];
struct Node {
  Data val;
  int lch, rch;
} rne[maxm * 20];
int fail[maxm];
int ch[maxm][26];
int len[maxm];
int n, m;
Data ans[maxn];
char s[maxn];
char t[maxn];
int rt[maxm];
int head[maxm];
int f[20][maxm];
int pos[maxn];
int Len[maxn];
int LL[maxn];
int last;
int root;
int cnt;
int tot;
int qvq;
void Pushup(int u) {
  if (!rne[u].lch && !rne[u].rch) return;
  if (rne[u].lch && !rne[u].rch)
    rne[u].val = rne[rne[u].lch].val;
  else if (rne[u].rch && !rne[u].lch)
    rne[u].val = rne[rne[u].rch].val;
  else
    rne[u].val = min(rne[rne[u].lch].val, rne[rne[u].rch].val);
}
void Modify(int& u, int l, int r, int x) {
  if (!u) u = ++qvq;
  if (l == r) {
    rne[u].val.sum++;
    rne[u].val.id = l;
    return;
  }
  int mid = l + r >> 1;
  if (x <= mid)
    Modify(rne[u].lch, l, mid, x);
  else
    Modify(rne[u].rch, mid + 1, r, x);
  Pushup(u);
}
void Extend(int x, int id) {
  int p = last, np = ++tot;
  last = np;
  len[np] = len[p] + 1;
  while (p && !ch[p][x]) ch[p][x] = np, p = fail[p];
  if (!p)
    fail[np] = root;
  else {
    int q = ch[p][x];
    if (len[q] == len[p] + 1)
      fail[np] = q;
    else {
      int nq = ++tot;
      fail[nq] = fail[q];
      len[nq] = len[p] + 1;
      memcpy(ch[nq], ch[q], sizeof ch[q]);
      fail[np] = fail[q] = nq;
      while (p && ch[p][x] == q) ch[p][x] = nq, p = fail[p];
    }
  }
  Modify(rt[np], 1, m, id);
}
int Merge(int x, int y, int l, int r) {
  if (!x || !y) return x + y;
  if (l == r) {
    int re = ++qvq;
    rne[re].val.sum = rne[x].val.sum + rne[y].val.sum;
    rne[re].val.id = l;
    return re;
  }
  int mid = l + r >> 1;
  int re = ++qvq;
  rne[re].lch = Merge(rne[x].lch, rne[y].lch, l, mid);
  rne[re].rch = Merge(rne[x].rch, rne[y].rch, mid + 1, r);
  Pushup(re);
  return re;
}
Data Query(int u, int l, int r, int L, int R) {
  if (l >= L && r <= R) return rne[u].val;
  int mid = l + r >> 1;
  Data re = (Data){-1, m + 1};
  if (L <= mid) re = min(re, Query(rne[u].lch, l, mid, L, R));
  if (R > mid) re = min(re, Query(rne[u].rch, mid + 1, r, L, R));
  return re;
}
void Dfs(int x, int p) {
  for (int i = head[x], y; y = E[i].to, i; i = E[i].last) {
    Dfs(y, x);
    rt[x] = Merge(rt[x], rt[y], 1, m);
  }
  for (Que cur : Q[x]) {
    ans[cur.id] = Query(rt[x], 1, m, cur.l, cur.r);
  }
}
void Adde(int x, int y) {
  E[++cnt] = (Edge){y, head[x]};
  head[x] = cnt;
}
int Read(char c = 0, int re = 0) {
  while (!isdigit(c = getchar()))
    ;
  re = c - '0';
  while (isdigit(c = getchar())) re = ((re << 2) + re << 1) + c - '0';
  return re;
}
int main() {
  scanf("%s", s + 1);
  n = strlen(s + 1);
  scanf("%d", &m);
  last = tot = root = 1;
  for (int i = 1; i <= m; ++i) {
    scanf("%s", t + 1);
    int len = strlen(t + 1);
    last = 1;
    for (int j = 1; j <= len; ++j) Extend(t[j] - 'a', i);
  }
  for (int i = 1; i <= tot; ++i) f[0][i] = fail[i];
  for (int i = 0; i < 19; ++i)
    for (int x = 1; x <= tot; ++x) f[i + 1][x] = f[i][f[i][x]];
  int x = 1, tmp = 0;
  for (int i = 1; i <= n; ++i) {
    int d = s[i] - 'a';
    if (ch[x][d])
      tmp++, x = ch[x][d];
    else {
      while (x && !ch[x][d]) x = fail[x];
      if (x)
        tmp = len[x] + 1, x = ch[x][d];
      else
        x = 1, tmp = 0;
    }
    pos[i] = x;
    Len[i] = tmp;
  }
  for (int i = 1; i <= tot; ++i)
    if (fail[i]) Adde(fail[i], i);
  int q = Read();
  for (int i = 1; i <= q; ++i) {
    int l = Read(), r = Read(), pl = Read(), pr = Read();
    LL[i] = l;
    if (Len[pr] < pr - pl + 1) {
      ans[i] = (Data){0, l};
      continue;
    }
    int rt = pos[pr];
    int LEN = pr - pl + 1;
    for (int i = 19; ~i; --i) {
      if (len[f[i][rt]] >= LEN) rt = f[i][rt];
    }
    Q[rt].push_back((Que){l, r, rt, i});
  }
  Dfs(1, 0);
  for (int i = 1; i <= q; ++i) {
    if (!ans[i].sum) ans[i].id = LL[i];
    printf("%d %d\n", ans[i].id, ans[i].sum);
  }
  return 0;
}
