#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10, L = 5e4 + 10, K = 30, P = 20;
int m;
char S[N], Ch[L];
int qu[N];
struct node {
  int id, x, u, v;
};
vector<node> que[N];
inline int cmp(node uu, node vv) { return uu.x < vv.x; }
int rt[L << 1], loc[L << 6], lc[L << 6], rc[L << 6], Cnt;
pair<int, int> val[L << 6];
inline pair<int, int> Mg(pair<int, int> x, pair<int, int> y) {
  if (x.first >= y.first) return make_pair(x.first, x.second);
  return make_pair(y.first, y.second);
}
void add(int &r, int x, int y, int k, int p) {
  r = ++Cnt;
  if (x == y) {
    val[r].first += p, val[r].second = x;
    return;
  }
  int md = (x + y) >> 1;
  if (k <= md)
    add(lc[r], x, md, k, p);
  else
    add(rc[r], md + 1, y, k, p);
  val[r] = Mg(val[lc[r]], val[rc[r]]);
}
int merge(int r1, int r2, int x, int y) {
  if (!r1 || !r2) return r1 | r2;
  int t = ++Cnt;
  if (x == y) {
    val[t].first = val[r1].first + val[r2].first;
    val[t].second = x;
    return t;
  }
  int md = (x + y) >> 1;
  lc[t] = merge(lc[r1], lc[r2], x, md);
  rc[t] = merge(rc[r1], rc[r2], md + 1, y);
  val[t] = Mg(val[lc[t]], val[rc[t]]);
  return t;
}
pair<int, int> query(int &r, int x, int y, int u, int v) {
  if (!r || u > v) return make_pair(0, 0);
  if (u <= x && y <= v) return val[r];
  int md = (x + y) >> 1;
  pair<int, int> res = make_pair(0, 0);
  if (u <= md) res = Mg(res, query(lc[r], x, md, u, v));
  if (md < v) res = Mg(res, query(rc[r], md + 1, y, u, v));
  return res;
}
int lst = 1, cnt = 1;
int mx[L << 1], ch[L << 1][K], pre[L << 1];
inline void insert(int c, int tp) {
  int np = ++cnt, p = lst;
  lst = np;
  mx[np] = mx[p] + 1;
  add(rt[np], 1, m, tp, 1);
  for (; p && !ch[p][c]; p = pre[p]) ch[p][c] = np;
  if (!p)
    pre[np] = 1;
  else {
    int q = ch[p][c];
    if (mx[q] == mx[p] + 1)
      pre[np] = q;
    else {
      int nq = ++cnt;
      mx[nq] = mx[p] + 1;
      memcpy(ch[nq], ch[q], sizeof ch[q]);
      pre[nq] = pre[q];
      pre[np] = pre[q] = nq;
      for (; p && ch[p][c] == q; p = pre[p]) ch[p][c] = nq;
    }
  }
}
vector<int> g[L << 1];
int fa[L << 1][P];
void dfs(int x, int f) {
  fa[x][0] = f;
  for (int i = 1; i <= 17; ++i) fa[x][i] = fa[fa[x][i - 1]][i - 1];
  for (int i = g[x].size() - 1; ~i; --i) {
    int k = g[x][i];
    dfs(k, x);
    rt[x] = merge(rt[x], rt[k], 1, m);
  }
}
pair<int, int> ans[N];
int main() {
  scanf("%s", S + 1);
  int n = strlen(S + 1);
  scanf("%d", &m);
  for (int tp = 1; tp <= m; ++tp) {
    lst = 1;
    scanf("%s", Ch + 1);
    int t = strlen(Ch + 1);
    for (int i = 1; i <= t; ++i) insert(Ch[i] - 'a' + 1, tp);
  }
  for (int i = 2; i <= cnt; ++i) g[pre[i]].push_back(i);
  dfs(1, 0);
  int p;
  scanf("%d", &p);
  for (int i = 1; i <= p; ++i) {
    int u, v, x, y;
    scanf("%d%d%d%d", &u, &v, &x, &y);
    qu[i] = u;
    que[y].push_back((node){i, x, u, v});
  }
  int pos = 1, len = 0;
  for (int t = 1; t <= n; ++t) {
    int c = S[t] - 'a' + 1;
    while (pos && !ch[pos][c]) pos = pre[pos], len = mx[pos];
    if (!pos) {
      pos = 1, len = 0;
      continue;
    }
    pos = ch[pos][c], ++len;
    for (int i = que[t].size() - 1; ~i; --i) {
      node w = que[t][i];
      if (t - w.x + 1 > len) continue;
      int ps = pos;
      for (int k = 17; ~k; --k)
        if (t - w.x + 1 <= mx[fa[ps][k]]) ps = fa[ps][k];
      ans[w.id] = query(rt[ps], 1, m, w.u, w.v);
    }
  }
  for (int i = 1; i <= p; ++i)
    if (!ans[i].first)
      printf("%d 0\n", qu[i]);
    else
      printf("%d %d\n", ans[i].second, ans[i].first);
  return 0;
}
