#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;   }   