RT,WA on 2/kel
#include<cstdio>
#include<cctype>
#define DEBUG printf("Baylor AK IOI!!!\n");
const int M=1e5+5;
int n,m,id[M],lg2[M],match[M];
char*it,s[M],str[M];
struct data{
int val,pos;
inline data(const int&val=0,const int&pos=0):val(val),pos(pos){}
inline bool operator<(const data&it)const{
return val==it.val?pos>it.pos:val<it.val;
}
};
inline data max(const data&a,const data&b){
return a<b?b:a;
}
struct Segment_Tree_Node{
int L,R;data val;
}t[M<<8];
int tnc;
inline void pushup(const int&u){
t[u].val=max(t[t[u].L].val,t[t[u].R].val);
}
void Add(int&u,int x,int L,int R){
if(!u)u=++tnc;
if(L==R)return void(t[u].val=data(++t[u].val.val,L));
int mid=L+R>>1;
if(x<=mid)Add(t[u].L,x,L,mid);
else Add(t[u].R,x,mid+1,R);
pushup(u);
}
int merge(int q,int p,int L,int R){
if(!q||!p)return q|p;
int id=++tnc;
if(L==R){
t[id].val=data(t[q].val.val+t[p].val.val,L);
return id;
}
int mid=L+R>>1;
t[id].L=merge(t[q].L,t[p].L,L,mid);
t[id].R=merge(t[q].R,t[p].R,mid+1,R);
pushup(id);
return id;
}
data Query(int u,int l,int r,int L,int R){
if(!u)return data(0,n+1);
if(l<=L&&R<=r)return t[u].val;
int mid=L+R>>1;data ans(0,n+1);
if(l<=mid)ans=max(ans,Query(t[u].L,l,r,L,mid));
if(r>mid)ans=max(ans,Query(t[u].R,l,r,mid+1,R));
return ans;
}
struct Edge{
int to;Edge*nx;
}e[M<<2],*h[M<<1],*tsc=e;
struct SAM_Node{
int f,len;
int chi[26];
}SAM[M<<1];
int cnt,lst,tot=1,d[M<<1],root[M<<1],f[M<<1][25];
inline void add(const int&u,const int&v){
*tsc=(Edge){v,h[u]};h[u]=tsc++;
}
inline int Insert(const int&s){
int q,p,nq,np,flag=0;
p=lst;
if(SAM[p].chi[s]&&SAM[SAM[p].chi[s]].len==SAM[p].len+1){
return SAM[lst].chi[s];
}
np=lst=++tot;
SAM[np].len=SAM[p].len+1;
for(;p&&!SAM[p].chi[s];p=SAM[p].f)SAM[p].chi[s]=np;
if(!p)SAM[np].f=1;
else{
q=SAM[p].chi[s];
if(SAM[q].len==SAM[p].len+1)SAM[np].f=q;
else{
if(SAM[p].len+1==SAM[np].len)flag=1;
SAM[nq=++tot]=SAM[q];
SAM[np].f=SAM[q].f=nq;
SAM[nq].len=SAM[p].len+1;
for(;p&&SAM[p].chi[s]==q;p=SAM[p].f)SAM[p].chi[s]=nq;
}
}
return flag?nq:np;
}
void DFS(int u){
d[u]=d[f[u][0]=SAM[u].f]+1;
for(int i=1;(1<<i)<=d[u];++i)f[u][i]=f[f[u][i-1]][i-1];
for(Edge*E=h[u];E;E=E->nx){
DFS(E->to);root[u]=merge(root[u],root[E->to],1,n);
}
}
inline void Build(char*str){
int i,s,now,len=0;
for(i=2;i<=tot;++i)add(SAM[i].f,i);
DFS(now=1);
for(i=1;isalpha(s=str[i]);++i){
s-=97;lg2[i]=lg2[i>>1]+1;
while(now&&!SAM[now].chi[s])len=SAM[now=SAM[now].f].len;
if(now)now=SAM[now].chi[s],++len;
else now=1;
id[i]=now;match[i]=len;
}
}
signed main(){
int i,k,l,r,L,R,now;lg2[i]=-1;
scanf("%s",s+1);
scanf("%d",&n);
for(i=1;i<=n;++i){
scanf("%s",str);it=str;lst=1;
while(isalpha(*it))Add(root[lst=Insert(*it-97)],i,1,n),*it++=0;
}
Build(s);scanf("%d",&m);
for(i=1;i<=m;++i){
scanf("%d%d%d%d",&l,&r,&L,&R);
now=id[R];
if(R-L+1>match[R])printf("%d 0\n",l);
else{
for(k=lg2[d[now]];~k;--k){
if(SAM[f[now][k]].len>=R-L+1)now=f[now][k];
}
data ans=Query(root[now],l,r,1,n);
if(!ans.pos)ans.pos=l;
printf("%d %d\n",ans.pos,ans.val);
}
}
}