/*
题面较难理解,意思就是求两个字符串的前缀的最长后缀,且这个后缀在所有的字符串中曾经出现过。
这个题目完美符合了fail树的最近公共祖先的定义。
因为它们的公用祖先一定是各自的后缀,且一定是最长的。
*/
#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#define N 1000010
#define mod 1000000007
#define lon long long
using namespace std;
int a[N][26],fa[N][21],dep[N],sum[N],pos[N*8],st[N],n,m,size=1,tot;
char s[N];
queue<int> q;
void insert(int id){
int len=strlen(s),now=1;st[id]=tot;
for(int i=0;i<len;i++){
int t=s[i]-‘a‘;
if(!a[now][t]){
a[now][t]=++size;
sum[size]=((lon)sum[now]*26+t)%mod;
}
now=a[now][t];
pos[++tot]=now;
}
}
void build(){
q.push(1);
while(!q.empty()){
int now=q.front();q.pop();
for(int i=0;i<26;i++){
if(!a[now][i]) continue;
int k=fa[now][0];
while(!a[k][i]) k=fa[k][0];
fa[a[now][i]][0]=a[k][i];
dep[a[now][i]]=dep[a[k][i]]+1;
q.push(a[now][i]);
}
}
}
void get_fa(){
for(int j=1;j<=20;j++)
for(int i=1;i<=size;i++)
fa[i][j]=fa[fa[i][j-1]][j-1];
}
int LCA(int u,int v){
if(dep[u]<dep[v]) swap(u,v);
int t=dep[u]-dep[v];
for(int i=0;i<=20;i++)
if(t&(1<<i)) u=fa[u][i];
if(u==v) return u;
for(int i=20;i>=0;i--)
if(fa[u][i]!=fa[v][i]){
u=fa[u][i];
v=fa[v][i];
}
return fa[u][0];
}
int main(){
for(int i=0;i<26;i++) a[0][i]=1;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s);
insert(i);
}
build();get_fa();
scanf("%d",&m);
for(int i=1;i<=m;i++){
int x1,x2,y1,y2;
scanf("%d%d%d%d",&x1,&x2,&y1,&y2);
int anc=LCA(pos[st[x1]+x2],pos[st[y1]+y2]);
printf("%d\n",sum[anc]);
}
return 0;
}