#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5, S = 26, M = 1e5 + 10;
int rt[N], n, m;
namespace SGT {
const int B = M << 6;
int ls[B], rs[B], tot;
pair<int, int> val[B];
inline void update(int id) {
  val[id] =
      (val[ls[id]].first >= val[rs[id]].first) ? val[ls[id]] : val[rs[id]];
}
void modify(int &id, int l, int r, int pos) {
  if (!id) id = ++tot;
  if (l == r) {
    ++val[id].first;
    val[id].second = pos;
    return;
  }
  if (pos <= ((l + r) >> 1))
    modify(ls[id], l, ((l + r) >> 1), pos);
  else
    modify(rs[id], ((l + r) >> 1) + 1, r, pos);
  update(id);
}
int merge(int x, int y, int l, int r) {
  if (!x || !y) return x + y;
  if (l == r) {
    int id = ++tot;
    val[id] = make_pair(val[x].first + val[y].first, l);
    return id;
  }
  int id = ++tot;
  ls[id] = merge(ls[x], ls[y], l, ((l + r) >> 1));
  rs[id] = merge(rs[x], rs[y], ((l + r) >> 1) + 1, r);
  update(id);
  return id;
}
pair<int, int> query(int id, int l, int r, int L, int R) {
  if (L <= l && r <= R) return val[id];
  if (R <= ((l + r) >> 1))
    return query(ls[id], l, ((l + r) >> 1), L, R);
  else if (L > ((l + r) >> 1))
    return query(rs[id], ((l + r) >> 1) + 1, r, L, R);
  else {
    pair<int, int> lans = query(ls[id], l, ((l + r) >> 1), L, R);
    pair<int, int> rans = query(rs[id], ((l + r) >> 1) + 1, r, L, R);
    if (lans.first >= rans.first)
      return lans;
    else
      return rans;
  }
}
}  // namespace SGT
struct Edge {
  int to, next;
} e[N << 1];
int head[N], ecnt;
inline void adde(int u, int v) {
  e[++ecnt].next = head[u];
  e[ecnt].to = v;
  head[u] = ecnt;
}
int Log2[N];
inline void init(int mx) {
  for (int i = 2; i <= mx; ++i) Log2[i] = Log2[i >> 1] + 1;
}
namespace SAM {
int ch[M][S], fa[M], tot = 1, len[M];
inline int insert(int c, int cur, vector<int> pos) {
  int id = ++tot;
  len[id] = len[cur] + 1;
  for (int val : pos) SGT::modify(rt[id], 1, m, val);
  for (; cur && !ch[cur][c]; cur = fa[cur]) ch[cur][c] = id;
  if (!cur) {
    fa[id] = 1;
    return id;
  }
  int q = ch[cur][c];
  if (len[q] == len[cur] + 1) {
    fa[id] = q;
    return id;
  }
  int x = ++tot;
  len[x] = len[cur] + 1;
  memcpy(ch[x], ch[q], S << 2);
  fa[x] = fa[q];
  fa[q] = fa[id] = x;
  for (; cur && ch[cur][c] == q; cur = fa[cur]) ch[cur][c] = x;
  return id;
}
inline void build() {
  init(tot);
  for (int i = 2; i <= tot; ++i) adde(fa[i], i);
}
}  // namespace SAM
namespace Trie {
int ch[M][S], tot = 1, fa[M];
vector<int> p[M];
inline void insert(char *s, int val) {
  int cur = 1, len = strlen(s + 1);
  for (int i = 1; i <= len; ++i) {
    if (!ch[cur][s[i] - 'a']) ch[cur][s[i] - 'a'] = ++tot, fa[tot] = cur;
    cur = ch[cur][s[i] - 'a'];
    p[cur].push_back(val);
  }
}
int pos[M];
inline void build() {
  queue<int> q;
  q.push(1);
  pos[1] = 1;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = 0; i < S; ++i) {
      if (!ch[u][i]) continue;
      pos[ch[u][i]] = SAM::insert(i, pos[u], p[ch[u][i]]);
      q.push(ch[u][i]);
    }
  }
}
}  // namespace Trie
using SAM::ch;
using SAM::fa;
using SAM::len;
int fat[M][20], dep[M];
void dfs(int u, int father) {
  fat[u][0] = father;
  dep[u] = dep[father] + 1;
  for (int i = 1; i <= Log2[dep[u]]; ++i) fat[u][i] = fat[fat[u][i - 1]][i - 1];
  for (int i = head[u], v; i; i = e[i].next) {
    v = e[i].to;
    dfs(v, u);
    rt[u] = SGT::merge(rt[u], rt[v], 1, m);
  }
}
char s[N], t[M];
int q;
int pos[N], lenth[N];
int main() {
  scanf("%s", s + 1);
  n = strlen(s + 1);
  scanf("%d", &m);
  for (int i = 1; i <= m; ++i) {
    scanf("%s", t + 1);
    Trie::insert(t, i);
  }
  Trie::build();
  SAM::build();
  dfs(1, 0);
  int cur = 1, mxlen = 0;
  for (int i = 1; i <= n; ++i) {
    if (ch[cur][s[i] - 'a'])
      ++mxlen, cur = ch[cur][s[i] - 'a'];
    else {
      while (cur && !ch[cur][s[i] - 'a']) cur = fa[cur];
      if (!cur)
        cur = 1, mxlen = 0;
      else
        mxlen = len[cur] + 1, cur = ch[cur][s[i] - 'a'];
    }
    lenth[i] = mxlen, pos[i] = cur;
  }
  scanf("%d", &q);
  int l, r, pl, prr;
  while (q--) {
    scanf("%d %d %d %d", &l, &r, &pl, &prr);
    int L = prr - pl + 1;
    if (lenth[prr] < L) {
      printf("%d %d\n", l, 0);
      continue;
    }
    int u = pos[prr];
    for (int i = Log2[dep[u]]; i >= 0; --i)
      if (len[fat[u][i]] >= L) u = fat[u][i];
    pair<int, int> ans = SGT::query(rt[u], 1, m, l, r);
    if (!ans.first)
      printf("%d %d\n", l, 0);
    else
      printf("%d %d\n", ans.second, ans.first);
  }
  return 0;
}
