#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD  1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef ll ValType;
template<typename  T> void maxtt(T& t1, T t2) {
    t1=max(t1,t2);
}
template<typename  T> void mintt(T& t1, T t2) {
    t1=min(t1,t2);
}
#define MAX 100135

bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et(int x=-1) {
    printf("%d\n", x); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) { return y?gcd1(y,x%y):x;}

vector<pair<int, char>> mp[MAX];
char fac[MAX];
//string ins="";
map<string, int> mpc;
int strId,Ans[MAX], dfn[MAX];
vector<int> spos[MAX*2];
int qylr(int id, int l, int r) {
    if(r<l) return 0;
    return upper_bound(spos[id].begin(), spos[id].end(), r) - lower_bound(spos[id].begin(), spos[id].end(), l);
}
struct mb {
    int u,v,id;
    string x, rx="";
    void  rd(int i) {
        id=i;
        cin>>u>>v>>x;
        if (mpc.find(x)==mpc.end()) mpc[x]=++strId;
        for(int i=(int)x.size()-1;~i;i--) rx.push_back(x[i]);
        if (mpc.find(rx)==mpc.end()) mpc[rx]=++strId;
    }
}qs[MAX];
struct kmp {
    int nxt[200];
    void init(string &str) {
        int k=-1,j=0;
        nxt[0]=-1;
        int plen=(int)str.size();
        while (j<plen) {
            while (k!=-1&&str[k]!=str[j]) k=nxt[k];
            nxt[++j]=++k;
        }
    }
    int Kmp(string &s, string &p) {
        int j=0,k=0,ans=0,slen=(int)s.size(),plen=(int)p.size();
        while (j<slen) {
            while (k!=-1&&s[j]!=p[k]) k=nxt[k];
            j++; k++;
            if (k==plen) {ans++;k=nxt[k];}
        }
        return ans;
    }
}KP;
struct Hld {
    int fa[MAX],bigSon[MAX],sz[MAX],deep[MAX], fap[MAX][20];
    int head[MAX];
    int dfid=0;
    void calSize(int x, int pa, char fc) {
        sz[x]=1; fa[x]=pa; deep[x]=deep[pa]+1;
        fac[x]=fc;
        fap[x][0]=pa;

        int mx = 0;
        for(auto cp: mp[x]) if (cp.first!=pa) {
            int c=cp.first;
            calSize(c, x, cp.second);
            sz[x]+=sz[c];
            if (mx < sz[c]) {
                mx = sz[c]; bigSon[x]=c;
            }
        }
    }
    void init(){
        for(int j=1; (1<<j)<=n; j++)
            for(int i=1; i<=n; i++)
                fap[i][j]=fap[fap[i][j-1]][j-1];
    }

    void build(int x, int H) {
        head[x]=H; dfn[x]=++dfid;

        if (mp[x].size()==1) {//leaf
            //build sam
            vector<int> ins;
            for(int tmp=x; ; tmp=fa[tmp]) {
                ins.push_back(tmp);
                if (tmp==H) break;
            }
            reverse(ins.begin(), ins.end());

            int N=ins.size();
            REP(i, N) {
                string x="";
                for(int j=i;j<min(N,i+100);j++) {
                    x.push_back(fac[ins[j]]);
                    if (mpc.find(x) != mpc.end()) {
                        spos[mpc[x]].push_back(dfn[ins[j]]);
                    }
                }
            }

        }
        if (bigSon[x] != 0) build(bigSon[x], H);
        for(auto c:mp[x]) if (c.first!=fa[x] && c.first!=bigSon[x]) {
            build(c.first, c.first);
        }
    }
    int lca(int x, int y) {
        while (head[x] != head[y]) {
            if (deep[head[x]] < deep[head[y]]) {
                swap(x,y);
            }
            x = fa[head[x]];
        }
        return deep[x]<deep[y] ? x : y;
    }

    string apped;
    int TT=0;
    void up(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            TT+=qylr(sid, dfn[head[x]], dfn[x]-sn+1);
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }
                REP(j, apped.size()) if (S.size()==sn+sn-2) break;
                else S+=apped[j];

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);
        if (sn<=1) return;

        int tmp = x;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+sn-1) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]+sn-1) tmp=fa[tmp];
        if(ff==tmp) return;
        string S="";
        while(tmp != ff && S.size()<sn+sn-2) {
            S+=fac[tmp]; tmp=fa[tmp];
        }
        REP(j, apped.size()) if (S.size()==sn+sn-2) break;
        else S+=apped[j];

        reverse(S.begin(), S.end());
        TT+=KP.Kmp(S, s);

    }
    bool DB=false;
    void down(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            if (DB) {
                cout<<deep[x]<<" "<<deep[H]<<endl;
            }
            TT+=qylr(sid, dfn[head[x]], dfn[x]-(sn-1));
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);

    }

    void cal(int qid) {
        int x=qs[qid].u, y=qs[qid].v;
        if(x==y) return;
        int ff = lca(x, y);
        DB  =debug && qid==6730;
//        if (debug && qid==6730) {
//            cout<<ff<<endl;
//            int tmp=x;
//            while(tmp!=ff) {
//                cout<<fac[tmp]; tmp=fa[tmp];
//            }cout<<endl;
//            tmp=y;
//            while(tmp!=ff) {
//                cout<<fac[tmp]; tmp=fa[tmp];
//            }cout<<endl;
//            exit(0);
//        }
        apped="";
        int tmp = y;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+100) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]) {
            apped += fac[tmp]; tmp=fa[tmp];
        }
        reverse(apped.begin(), apped.end());
        TT=0;
        KP.init(qs[qid].rx);
        up(x,ff,qs[qid].rx, (int)qs[qid].rx.size(), mpc[qs[qid].rx]);
        KP.init(qs[qid].x);
        down(y,ff,qs[qid].x, (int)qs[qid].x.size(), mpc[qs[qid].x]);
        Ans[qs[qid].id] =TT;
        if (DB) exit(0);
    }
}ynk;
void fmain(int tid) {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    cin>>n;
    debug = n==50000;

    REP(i,n-1) {
        int u,v; char c; cin>>u>>v>>c;
        mp[u].push_back({v,c});
        mp[v].push_back({u,c});
    }
    cin>>m;
    REQ(i,m) {
        qs[i].rd(i);
    }

    ynk.calSize(1, 0, ' ');
    ynk.build(1, 1);
    ynk.init();

    REQ(i,m) {
        ynk.cal(i);
        if (debug && i==6730) {
            cout<<qs[i].u<<" "<<qs[i].v<<" "<<qs[i].x;
            return;
        }
    }
    REQ(i,m) cout<<Ans[i]<<endl;
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD  1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef ll ValType;
template<typename  T> void maxtt(T& t1, T t2) {
    t1=max(t1,t2);
}
template<typename  T> void mintt(T& t1, T t2) {
    t1=min(t1,t2);
}
#define MAX 100135

bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et(int x=-1) {
    printf("%d\n", x); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) { return y?gcd1(y,x%y):x;}

vector<pair<int, char>> mp[MAX];
char fac[MAX];
//string ins="";
map<string, int> mpc;
int strId,Ans[MAX], dfn[MAX];
vector<int> spos[MAX*2];
int qylr(int id, int l, int r) {
    if(r<l) return 0;
    return upper_bound(spos[id].begin(), spos[id].end(), r) - lower_bound(spos[id].begin(), spos[id].end(), l);
}
struct mb {
    int u,v,id;
    string x, rx="";
    void  rd(int i) {
        id=i;
        cin>>u>>v>>x;
        if (mpc.find(x)==mpc.end()) mpc[x]=++strId;
        for(int i=(int)x.size()-1;~i;i--) rx.push_back(x[i]);
        if (mpc.find(rx)==mpc.end()) mpc[rx]=++strId;
    }
}qs[MAX];
struct kmp {
    int nxt[200];
    void init(string &str) {
        int k=-1,j=0;
        nxt[0]=-1;
        int plen=(int)str.size();
        while (j<plen) {
            while (k!=-1&&str[k]!=str[j]) k=nxt[k];
            nxt[++j]=++k;
        }
    }
    int Kmp(string &s, string &p) {
        int j=0,k=0,ans=0,slen=(int)s.size(),plen=(int)p.size();
        while (j<slen) {
            while (k!=-1&&s[j]!=p[k]) k=nxt[k];
            j++; k++;
            if (k==plen) {ans++;k=nxt[k];}
        }
        return ans;
    }
}KP;
struct Hld {
    int fa[MAX],bigSon[MAX],sz[MAX],deep[MAX], fap[MAX][20];
    int head[MAX];
    int dfid=0;
    void calSize(int x, int pa, char fc) {
        sz[x]=1; fa[x]=pa; deep[x]=deep[pa]+1;
        fac[x]=fc;
        fap[x][0]=pa;

        int mx = 0;
        for(auto cp: mp[x]) if (cp.first!=pa) {
            int c=cp.first;
            calSize(c, x, cp.second);
            sz[x]+=sz[c];
            if (mx < sz[c]) {
                mx = sz[c]; bigSon[x]=c;
            }
        }
    }
    void init(){
        for(int j=1; (1<<j)<=n; j++)
            for(int i=1; i<=n; i++)
                fap[i][j]=fap[fap[i][j-1]][j-1];
    }

    void build(int x, int H) {
        head[x]=H; dfn[x]=++dfid;

        if (mp[x].size()==1) {//leaf
            //build sam
            vector<int> ins;
            for(int tmp=x; ; tmp=fa[tmp]) {
                ins.push_back(tmp);
                if (tmp==H) break;
            }
            reverse(ins.begin(), ins.end());

            int N=ins.size();
            REP(i, N) {
                string x="";
                for(int j=i;j<min(N,i+100);j++) {
                    x.push_back(fac[ins[j]]);
                    if (mpc.find(x) != mpc.end()) {
                        spos[mpc[x]].push_back(dfn[ins[j]]);
                    }
                }
            }

        }
        if (bigSon[x] != 0) build(bigSon[x], H);
        for(auto c:mp[x]) if (c.first!=fa[x] && c.first!=bigSon[x]) {
            build(c.first, c.first);
        }
    }
    int lca(int x, int y) {
        while (head[x] != head[y]) {
            if (deep[head[x]] < deep[head[y]]) {
                swap(x,y);
            }
            x = fa[head[x]];
        }
        return deep[x]<deep[y] ? x : y;
    }

    string apped;
    int TT=0;
    void up(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            TT+=qylr(sid, dfn[head[x]], dfn[x]-sn+1);
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }
                REP(j, apped.size()) if (S.size()==sn+sn-2) break;
                else S+=apped[j];

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);
        if (sn<=1) return;

        int tmp = x;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+sn-1) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]+sn-1) tmp=fa[tmp];
        if(ff==tmp) return;
        string S="";
        while(tmp != ff && S.size()<sn+sn-2) {
            S+=fac[tmp]; tmp=fa[tmp];
        }
        REP(j, apped.size()) if (S.size()==sn+sn-2) break;
        else S+=apped[j];

        reverse(S.begin(), S.end());
        TT+=KP.Kmp(S, s);

    }
    bool DB=false;
    void down(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            if (DB) {
                cout<<H<<" ";
            }
            TT+=qylr(sid, dfn[head[x]], dfn[x]-(sn-1));
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);

    }

    void cal(int qid) {
        int x=qs[qid].u, y=qs[qid].v;
        if(x==y) return;
        int ff = lca(x, y);
        DB  =debug && qid==6730;
//        if (debug && qid==6730) {
//            cout<<ff<<endl;
//            int tmp=x;
//            while(tmp!=ff) {
//                cout<<fac[tmp]; tmp=fa[tmp];
//            }cout<<endl;
//            tmp=y;
//            while(tmp!=ff) {
//                cout<<fac[tmp]; tmp=fa[tmp];
//            }cout<<endl;
//            exit(0);
//        }
        apped="";
        int tmp = y;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+100) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]) {
            apped += fac[tmp]; tmp=fa[tmp];
        }
        reverse(apped.begin(), apped.end());
        TT=0;
        KP.init(qs[qid].rx);
        up(x,ff,qs[qid].rx, (int)qs[qid].rx.size(), mpc[qs[qid].rx]);
        KP.init(qs[qid].x);
        down(y,ff,qs[qid].x, (int)qs[qid].x.size(), mpc[qs[qid].x]);
        Ans[qs[qid].id] =TT;
        if (DB) exit(0);
    }
}ynk;
void fmain(int tid) {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    cin>>n;
    debug = n==50000;

    REP(i,n-1) {
        int u,v; char c; cin>>u>>v>>c;
        mp[u].push_back({v,c});
        mp[v].push_back({u,c});
    }
    cin>>m;
    REQ(i,m) {
        qs[i].rd(i);
    }

    ynk.calSize(1, 0, ' ');
    ynk.build(1, 1);
    ynk.init();

    REQ(i,m) {
        ynk.cal(i);
        if (debug && i==6730) {
            cout<<qs[i].u<<" "<<qs[i].v<<" "<<qs[i].x;
            return;
        }
    }
    REQ(i,m) cout<<Ans[i]<<endl;
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD  1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef ll ValType;
template<typename  T> void maxtt(T& t1, T t2) {
    t1=max(t1,t2);
}
template<typename  T> void mintt(T& t1, T t2) {
    t1=min(t1,t2);
}
#define MAX 100135

bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et(int x=-1) {
    printf("%d\n", x); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) { return y?gcd1(y,x%y):x;}

vector<pair<int, char>> mp[MAX];
char fac[MAX];
//string ins="";
map<string, int> mpc;
int strId,Ans[MAX], dfn[MAX];
vector<int> spos[MAX*2];
int qylr(int id, int l, int r) {
    if(r<l) return 0;
    return upper_bound(spos[id].begin(), spos[id].end(), r) - lower_bound(spos[id].begin(), spos[id].end(), l);
}
struct mb {
    int u,v,id;
    string x, rx="";
    void  rd(int i) {
        id=i;
        cin>>u>>v>>x;
        if (mpc.find(x)==mpc.end()) mpc[x]=++strId;
        for(int i=(int)x.size()-1;~i;i--) rx.push_back(x[i]);
        if (mpc.find(rx)==mpc.end()) mpc[rx]=++strId;
    }
}qs[MAX];
struct kmp {
    int nxt[200];
    void init(string &str) {
        int k=-1,j=0;
        nxt[0]=-1;
        int plen=(int)str.size();
        while (j<plen) {
            while (k!=-1&&str[k]!=str[j]) k=nxt[k];
            nxt[++j]=++k;
        }
    }
    int Kmp(string &s, string &p) {
        int j=0,k=0,ans=0,slen=(int)s.size(),plen=(int)p.size();
        while (j<slen) {
            while (k!=-1&&s[j]!=p[k]) k=nxt[k];
            j++; k++;
            if (k==plen) {ans++;k=nxt[k];}
        }
        return ans;
    }
}KP;
struct Hld {
    int fa[MAX],bigSon[MAX],sz[MAX],deep[MAX], fap[MAX][20];
    int head[MAX];
    int dfid=0;
    void calSize(int x, int pa, char fc) {
        sz[x]=1; fa[x]=pa; deep[x]=deep[pa]+1;
        fac[x]=fc;
        fap[x][0]=pa;

        int mx = 0;
        for(auto cp: mp[x]) if (cp.first!=pa) {
            int c=cp.first;
            calSize(c, x, cp.second);
            sz[x]+=sz[c];
            if (mx < sz[c]) {
                mx = sz[c]; bigSon[x]=c;
            }
        }
    }
    void init(){
        for(int j=1; (1<<j)<=n; j++)
            for(int i=1; i<=n; i++)
                fap[i][j]=fap[fap[i][j-1]][j-1];
    }

    void build(int x, int H) {
        head[x]=H; dfn[x]=++dfid;

        if (mp[x].size()==1) {//leaf
            //build sam
            vector<int> ins;
            for(int tmp=x; ; tmp=fa[tmp]) {
                ins.push_back(tmp);
                if (tmp==H) break;
            }
            reverse(ins.begin(), ins.end());

            int N=ins.size();
            REP(i, N) {
                string x="";
                for(int j=i;j<min(N,i+100);j++) {
                    x.push_back(fac[ins[j]]);
                    if (mpc.find(x) != mpc.end()) {
                        spos[mpc[x]].push_back(dfn[ins[j]]);
                    }
                }
            }

        }
        if (bigSon[x] != 0) build(bigSon[x], H);
        for(auto c:mp[x]) if (c.first!=fa[x] && c.first!=bigSon[x]) {
            build(c.first, c.first);
        }
    }
    int lca(int x, int y) {
        while (head[x] != head[y]) {
            if (deep[head[x]] < deep[head[y]]) {
                swap(x,y);
            }
            x = fa[head[x]];
        }
        return deep[x]<deep[y] ? x : y;
    }

    string apped;
    int TT=0;
    void up(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            TT+=qylr(sid, dfn[head[x]], dfn[x]-sn+1);
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }
                REP(j, apped.size()) if (S.size()==sn+sn-2) break;
                else S+=apped[j];

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);
        if (sn<=1) return;

        int tmp = x;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+sn-1) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]+sn-1) tmp=fa[tmp];
        if(ff==tmp) return;
        string S="";
        while(tmp != ff && S.size()<sn+sn-2) {
            S+=fac[tmp]; tmp=fa[tmp];
        }
        REP(j, apped.size()) if (S.size()==sn+sn-2) break;
        else S+=apped[j];

        reverse(S.begin(), S.end());
        TT+=KP.Kmp(S, s);

    }
    void down(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            TT+=qylr(sid, dfn[head[x]], dfn[x]-(sn-1));
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);

    }

    void cal(int qid) {
        int x=qs[qid].u, y=qs[qid].v;
        if(x==y) return;
        int ff = lca(x, y);
        if (debug && qid==6730) {
            cout<<ff<<endl;
            cout<<deep[x]<<" "<<deep[y]<<" "<<deep[ff]<<endl; exit(0);
        }
        apped="";
        int tmp = y;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+100) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]) {
            apped += fac[tmp]; tmp=fa[tmp];
        }
        reverse(apped.begin(), apped.end());
        TT=0;
        KP.init(qs[qid].rx);
        up(x,ff,qs[qid].rx, (int)qs[qid].rx.size(), mpc[qs[qid].rx]);
        KP.init(qs[qid].x);
        down(y,ff,qs[qid].x, (int)qs[qid].x.size(), mpc[qs[qid].x]);
        Ans[qs[qid].id] =TT;
    }
}ynk;
void fmain(int tid) {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    cin>>n;
    debug = n==50000;

    REP(i,n-1) {
        int u,v; char c; cin>>u>>v>>c;
        mp[u].push_back({v,c});
        mp[v].push_back({u,c});
    }
    cin>>m;
    REQ(i,m) {
        qs[i].rd(i);
    }

    ynk.calSize(1, 0, ' ');
    ynk.build(1, 1);
    ynk.init();

    REQ(i,m) {
        ynk.cal(i);
        if (debug && i==6730) {
            cout<<qs[i].u<<" "<<qs[i].v<<" "<<qs[i].x;
            return;
        }
    }
    REQ(i,m) cout<<Ans[i]<<endl;
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD  1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef ll ValType;
template<typename  T> void maxtt(T& t1, T t2) {
    t1=max(t1,t2);
}
template<typename  T> void mintt(T& t1, T t2) {
    t1=min(t1,t2);
}
#define MAX 100135

bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et(int x=-1) {
    printf("%d\n", x); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) { return y?gcd1(y,x%y):x;}

vector<pair<int, char>> mp[MAX];
char fac[MAX];
//string ins="";
map<string, int> mpc;
int strId,Ans[MAX], dfn[MAX];
vector<int> spos[MAX*2];
int qylr(int id, int l, int r) {
    if(r<l) return 0;
    return upper_bound(spos[id].begin(), spos[id].end(), r) - lower_bound(spos[id].begin(), spos[id].end(), l);
}
struct mb {
    int u,v,id;
    string x, rx="";
    void  rd(int i) {
        id=i;
        cin>>u>>v>>x;
        if (mpc.find(x)==mpc.end()) mpc[x]=++strId;
        for(int i=(int)x.size()-1;~i;i--) rx.push_back(x[i]);
        if (mpc.find(rx)==mpc.end()) mpc[rx]=++strId;
    }
}qs[MAX];
struct kmp {
    int nxt[200];
    void init(string &str) {
        int k=-1,j=0;
        nxt[0]=-1;
        int plen=(int)str.size();
        while (j<plen) {
            while (k!=-1&&str[k]!=str[j]) k=nxt[k];
            nxt[++j]=++k;
        }
    }
    int Kmp(string &s, string &p) {
        int j=0,k=0,ans=0,slen=(int)s.size(),plen=(int)p.size();
        while (j<slen) {
            while (k!=-1&&s[j]!=p[k]) k=nxt[k];
            j++; k++;
            if (k==plen) {ans++;k=nxt[k];}
        }
        return ans;
    }
}KP;
struct Hld {
    int fa[MAX],bigSon[MAX],sz[MAX],deep[MAX], fap[MAX][20];
    int head[MAX];
    int dfid=0;
    void calSize(int x, int pa, char fc) {
        sz[x]=1; fa[x]=pa; deep[x]=deep[pa]+1;
        fac[x]=fc;
        fap[x][0]=pa;

        int mx = 0;
        for(auto cp: mp[x]) if (cp.first!=pa) {
            int c=cp.first;
            calSize(c, x, cp.second);
            sz[x]+=sz[c];
            if (mx < sz[c]) {
                mx = sz[c]; bigSon[x]=c;
            }
        }
    }
    void init(){
        for(int j=1; (1<<j)<=n; j++)
            for(int i=1; i<=n; i++)
                fap[i][j]=fap[fap[i][j-1]][j-1];
    }

    void build(int x, int H) {
        head[x]=H; dfn[x]=++dfid;

        if (mp[x].size()==1) {//leaf
            //build sam
            vector<int> ins;
            for(int tmp=x; ; tmp=fa[tmp]) {
                ins.push_back(tmp);
                if (tmp==H) break;
            }
            reverse(ins.begin(), ins.end());

            int N=ins.size();
            REP(i, N) {
                string x="";
                for(int j=i;j<min(N,i+100);j++) {
                    x.push_back(fac[ins[j]]);
                    if (mpc.find(x) != mpc.end()) {
                        spos[mpc[x]].push_back(dfn[ins[j]]);
                    }
                }
            }

        }
        if (bigSon[x] != 0) build(bigSon[x], H);
        for(auto c:mp[x]) if (c.first!=fa[x] && c.first!=bigSon[x]) {
            build(c.first, c.first);
        }
    }
    int lca(int x, int y) {
        while (head[x] != head[y]) {
            if (deep[head[x]] < deep[head[y]]) {
                swap(x,y);
            }
            x = fa[head[x]];
        }
        return deep[x]<deep[y] ? x : y;
    }

    string apped;
    int TT=0;
    void up(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            TT+=qylr(sid, dfn[head[x]], dfn[x]-sn+1);
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }
                REP(j, apped.size()) if (S.size()==sn+sn-2) break;
                else S+=apped[j];

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);
        if (sn<=1) return;

        int tmp = x;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+sn-1) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]+sn-1) tmp=fa[tmp];
        if(ff==tmp) return;
        string S="";
        while(tmp != ff && S.size()<sn+sn-2) {
            S+=fac[tmp]; tmp=fa[tmp];
        }
        REP(j, apped.size()) if (S.size()==sn+sn-2) break;
        else S+=apped[j];

        reverse(S.begin(), S.end());
        TT+=KP.Kmp(S, s);

    }
    bool DB=false;
    void down(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            if (DB && deep[x]==128) {
                int tmp=x;
                while(1) {
                    cout<<dfn[tmp]<<" ";
                    if(tmp==H) break;
                    tmp=fa[tmp];
                }cout<<endl;
                //13320
                int id =mpc["qx"];
                cout<<spos[id].size()<<endl;
                for(int z: spos[id]) if (z<=dfn[x] && z>=dfn[H]) cout<<z<<" ";
                exit(0);
            }
            TT+=qylr(sid, dfn[head[x]], dfn[x]-(sn-1));
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);

    }

    void cal(int qid) {
        int x=qs[qid].u, y=qs[qid].v;
        if(x==y) return;
        int ff = lca(x, y);
        DB  =debug && qid==6730;
//        if (debug && qid==6730) {
//            cout<<ff<<endl;
//            int tmp=x;
//            while(tmp!=ff) {
//                cout<<fac[tmp]; tmp=fa[tmp];
//            }cout<<endl;
//            tmp=y;
//            while(tmp!=ff) {
//                cout<<fac[tmp]; tmp=fa[tmp];
//            }cout<<endl;
//            exit(0);
//        }
        apped="";
        int tmp = y;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+100) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]) {
            apped += fac[tmp]; tmp=fa[tmp];
        }
        reverse(apped.begin(), apped.end());
        TT=0;
        KP.init(qs[qid].rx);
        up(x,ff,qs[qid].rx, (int)qs[qid].rx.size(), mpc[qs[qid].rx]);
        KP.init(qs[qid].x);
        down(y,ff,qs[qid].x, (int)qs[qid].x.size(), mpc[qs[qid].x]);
        Ans[qs[qid].id] =TT;
        if (DB) exit(0);
    }
}ynk;
void fmain(int tid) {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    cin>>n;
    debug = n==50000;

    REP(i,n-1) {
        int u,v; char c; cin>>u>>v>>c;
        mp[u].push_back({v,c});
        mp[v].push_back({u,c});
    }
    cin>>m;
    REQ(i,m) {
        qs[i].rd(i);
    }

    ynk.calSize(1, 0, ' ');
    ynk.build(1, 1);
    ynk.init();

    REQ(i,m) {
        ynk.cal(i);
        if (debug && i==6730) {
            cout<<qs[i].u<<" "<<qs[i].v<<" "<<qs[i].x;
            return;
        }
    }
    REQ(i,m) cout<<Ans[i]<<endl;
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD  1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef ll ValType;
template<typename  T> void maxtt(T& t1, T t2) {
    t1=max(t1,t2);
}
template<typename  T> void mintt(T& t1, T t2) {
    t1=min(t1,t2);
}
#define MAX 100135

bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et(int x=-1) {
    printf("%d\n", x); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) { return y?gcd1(y,x%y):x;}

vector<pair<int, char>> mp[MAX];
char fac[MAX];
//string ins="";
map<string, int> mpc;
int strId,Ans[MAX], dfn[MAX];
vector<int> spos[MAX*2];
int qylr(int id, int l, int r) {
    if(r<l) return 0;
    return upper_bound(spos[id].begin(), spos[id].end(), r) - lower_bound(spos[id].begin(), spos[id].end(), l);
}
struct mb {
    int u,v,id;
    string x, rx="";
    void  rd(int i) {
        id=i;
        cin>>u>>v>>x;
        if (mpc.find(x)==mpc.end()) mpc[x]=++strId;
        for(int i=(int)x.size()-1;~i;i--) rx.push_back(x[i]);
        if (mpc.find(rx)==mpc.end()) mpc[rx]=++strId;
    }
}qs[MAX];
struct kmp {
    int nxt[200];
    void init(string &str) {
        int k=-1,j=0;
        nxt[0]=-1;
        int plen=(int)str.size();
        while (j<plen) {
            while (k!=-1&&str[k]!=str[j]) k=nxt[k];
            nxt[++j]=++k;
        }
    }
    int Kmp(string &s, string &p) {
        int j=0,k=0,ans=0,slen=(int)s.size(),plen=(int)p.size();
        while (j<slen) {
            while (k!=-1&&s[j]!=p[k]) k=nxt[k];
            j++; k++;
            if (k==plen) {ans++;k=nxt[k];}
        }
        return ans;
    }
}KP;
struct Hld {
    int fa[MAX],bigSon[MAX],sz[MAX],deep[MAX], fap[MAX][20];
    int head[MAX];
    int dfid=0;
    void calSize(int x, int pa, char fc) {
        sz[x]=1; fa[x]=pa; deep[x]=deep[pa]+1;
        fac[x]=fc;
        fap[x][0]=pa;

        int mx = 0;
        for(auto cp: mp[x]) if (cp.first!=pa) {
            int c=cp.first;
            calSize(c, x, cp.second);
            sz[x]+=sz[c];
            if (mx < sz[c]) {
                mx = sz[c]; bigSon[x]=c;
            }
        }
    }
    void init(){
        for(int j=1; (1<<j)<=n; j++)
            for(int i=1; i<=n; i++)
                fap[i][j]=fap[fap[i][j-1]][j-1];
    }

    void build(int x, int H) {
        head[x]=H; dfn[x]=++dfid;

        if (mp[x].size()==1) {//leaf
            //build sam
            vector<int> ins;
            for(int tmp=x; ; tmp=fa[tmp]) {
                ins.push_back(tmp);
                if (tmp==H) break;
            }
            reverse(ins.begin(), ins.end());

            int N=ins.size();
            REP(i, N) {
                string x="";
                for(int j=i;j<min(N,i+100);j++) {
                    x.push_back(fac[ins[j]]);
                    if (mpc.find(x) != mpc.end()) {
                        spos[mpc[x]].push_back(dfn[ins[j]]);
                    }
                }
            }

        }
        if (bigSon[x] != 0) build(bigSon[x], H);
        for(auto c:mp[x]) if (c.first!=fa[x] && c.first!=bigSon[x]) {
            build(c.first, c.first);
        }
    }
    int lca(int x, int y) {
        while (head[x] != head[y]) {
            if (deep[head[x]] < deep[head[y]]) {
                swap(x,y);
            }
            x = fa[head[x]];
        }
        return deep[x]<deep[y] ? x : y;
    }

    string apped;
    int TT=0;
    void up(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            TT+=qylr(sid, dfn[head[x]], dfn[x]-sn+1);
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }
                REP(j, apped.size()) if (S.size()==sn+sn-2) break;
                else S+=apped[j];

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);
        if (sn<=1) return;

        int tmp = x;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+sn-1) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]+sn-1) tmp=fa[tmp];
        if(ff==tmp) return;
        string S="";
        while(tmp != ff && S.size()<sn+sn-2) {
            S+=fac[tmp]; tmp=fa[tmp];
        }
        REP(j, apped.size()) if (S.size()==sn+sn-2) break;
        else S+=apped[j];

        reverse(S.begin(), S.end());
        TT+=KP.Kmp(S, s);

    }
    void down(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            TT+=qylr(sid, dfn[head[x]], dfn[x]-(sn-1));
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);

    }

    void cal(int qid) {
        int x=qs[qid].u, y=qs[qid].v;
        if(x==y) return;
        int ff = lca(x, y);
        if (debug && qid==6730) {
            cout<<ff<<endl;
            int tmp=x;
            while(tmp!=ff) {
                cout<<fac[tmp]; tmp=fa[tmp];
            }cout<<endl;
            tmp=y;
            while(tmp!=ff) {
                cout<<fac[tmp]; tmp=fa[tmp];
            }cout<<endl;
            exit(0);
        }
        apped="";
        int tmp = y;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+100) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]) {
            apped += fac[tmp]; tmp=fa[tmp];
        }
        reverse(apped.begin(), apped.end());
        TT=0;
        KP.init(qs[qid].rx);
        up(x,ff,qs[qid].rx, (int)qs[qid].rx.size(), mpc[qs[qid].rx]);
        KP.init(qs[qid].x);
        down(y,ff,qs[qid].x, (int)qs[qid].x.size(), mpc[qs[qid].x]);
        Ans[qs[qid].id] =TT;
    }
}ynk;
void fmain(int tid) {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    cin>>n;
    debug = n==50000;

    REP(i,n-1) {
        int u,v; char c; cin>>u>>v>>c;
        mp[u].push_back({v,c});
        mp[v].push_back({u,c});
    }
    cin>>m;
    REQ(i,m) {
        qs[i].rd(i);
    }

    ynk.calSize(1, 0, ' ');
    ynk.build(1, 1);
    ynk.init();

    REQ(i,m) {
        ynk.cal(i);
        if (debug && i==6730) {
            cout<<qs[i].u<<" "<<qs[i].v<<" "<<qs[i].x;
            return;
        }
    }
    REQ(i,m) cout<<Ans[i]<<endl;
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD  1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef ll ValType;
template<typename  T> void maxtt(T& t1, T t2) {
    t1=max(t1,t2);
}
template<typename  T> void mintt(T& t1, T t2) {
    t1=min(t1,t2);
}
#define MAX 100135

bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et(int x=-1) {
    printf("%d\n", x); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) { return y?gcd1(y,x%y):x;}

vector<pair<int, char>> mp[MAX];
char fac[MAX];
//string ins="";
map<string, int> mpc;
int strId,Ans[MAX], dfn[MAX];
vector<int> spos[MAX*2];
int qylr(int id, int l, int r) {
    if(r<l) return 0;
    return upper_bound(spos[id].begin(), spos[id].end(), r) - lower_bound(spos[id].begin(), spos[id].end(), l);
}
struct mb {
    int u,v,id;
    string x, rx="";
    void  rd(int i) {
        id=i;
        cin>>u>>v>>x;
        if (mpc.find(x)==mpc.end()) mpc[x]=++strId;
        for(int i=(int)x.size()-1;~i;i--) rx.push_back(x[i]);
        if (mpc.find(rx)==mpc.end()) mpc[rx]=++strId;
    }
}qs[MAX];
struct kmp {
    int nxt[200];
    void init(string &str) {
        int k=-1,j=0;
        nxt[0]=-1;
        int plen=(int)str.size();
        while (j<plen) {
            while (k!=-1&&str[k]!=str[j]) k=nxt[k];
            nxt[++j]=++k;
        }
    }
    int Kmp(string &s, string &p) {
        int j=0,k=0,ans=0,slen=(int)s.size(),plen=(int)p.size();
        while (j<slen) {
            while (k!=-1&&s[j]!=p[k]) k=nxt[k];
            j++; k++;
            if (k==plen) {ans++;k=nxt[k];}
        }
        return ans;
    }
}KP;
struct Hld {
    int fa[MAX],bigSon[MAX],sz[MAX],deep[MAX], fap[MAX][20];
    int head[MAX];
    int dfid=0;
    void calSize(int x, int pa, char fc) {
        sz[x]=1; fa[x]=pa; deep[x]=deep[pa]+1;
        fac[x]=fc;
        fap[x][0]=pa;

        int mx = 0;
        for(auto cp: mp[x]) if (cp.first!=pa) {
            int c=cp.first;
            calSize(c, x, cp.second);
            sz[x]+=sz[c];
            if (mx < sz[c]) {
                mx = sz[c]; bigSon[x]=c;
            }
        }
    }
    void init(){
        for(int j=1; (1<<j)<=n; j++)
            for(int i=1; i<=n; i++)
                fap[i][j]=fap[fap[i][j-1]][j-1];
    }

    void build(int x, int H) {
        head[x]=H; dfn[x]=++dfid;

        if (mp[x].size()==1) {//leaf
            //build sam
            vector<int> ins;
            for(int tmp=x; ; tmp=fa[tmp]) {
                ins.push_back(tmp);
                if (tmp==H) break;
            }
            reverse(ins.begin(), ins.end());

            int N=ins.size();
            REP(i, N) {
                string x="";
                for(int j=i;j<min(N,i+100);j++) {
                    x.push_back(fac[ins[j]]);
                    if (mpc.find(x) != mpc.end()) {
                        spos[mpc[x]].push_back(dfn[ins[j]]);
                    }
                }
            }

        }
        if (bigSon[x] != 0) build(bigSon[x], H);
        for(auto c:mp[x]) if (c.first!=fa[x] && c.first!=bigSon[x]) {
            build(c.first, c.first);
        }
    }
    int lca(int x, int y) {
        while (head[x] != head[y]) {
            if (deep[head[x]] < deep[head[y]]) {
                swap(x,y);
            }
            x = fa[head[x]];
        }
        return deep[x]<deep[y] ? x : y;
    }

    string apped;
    int TT=0;
    void up(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            TT+=qylr(sid, dfn[head[x]], dfn[x]-sn+1);
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }
                REP(j, apped.size()) if (S.size()==sn+sn-2) break;
                else S+=apped[j];

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);
        if (sn<=1) return;

        int tmp = x;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+sn-1) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]+sn-1) tmp=fa[tmp];
        if(ff==tmp) return;
        string S="";
        while(tmp != ff && S.size()<sn+sn-2) {
            S+=fac[tmp]; tmp=fa[tmp];
        }
        REP(j, apped.size()) if (S.size()==sn+sn-2) break;
        else S+=apped[j];

        reverse(S.begin(), S.end());
        TT+=KP.Kmp(S, s);

    }
    void down(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            TT+=qylr(sid, dfn[head[x]], dfn[x]-(sn-1));
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);

    }

    void cal(int qid) {
        int x=qs[qid].u, y=qs[qid].v;
        if(x==y) return;
        int ff = lca(x, y);
        apped="";
        int tmp = y;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+100) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]) {
            apped += fac[tmp]; tmp=fa[tmp];
        }
        reverse(apped.begin(), apped.end());
        TT=0;
        KP.init(qs[qid].rx);
        up(x,ff,qs[qid].rx, (int)qs[qid].rx.size(), mpc[qs[qid].rx]);
        KP.init(qs[qid].x);
        down(y,ff,qs[qid].x, (int)qs[qid].x.size(), mpc[qs[qid].x]);
        Ans[qs[qid].id] =TT;
    }
}ynk;
void fmain(int tid) {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    cin>>n;
    REP(i,n-1) {
        int u,v; char c; cin>>u>>v>>c;
        mp[u].push_back({v,c});
        mp[v].push_back({u,c});
    }
    cin>>m;
    REQ(i,m) {
        qs[i].rd(i);
    }

    ynk.calSize(1, 0, ' ');
    ynk.build(1, 1);
    ynk.init();

    REQ(i,m) {
        ynk.cal(i);
    }
    REQ(i,m) cout<<Ans[i]<<endl;
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD  1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef ll ValType;
template<typename  T> void maxtt(T& t1, T t2) {
    t1=max(t1,t2);
}
template<typename  T> void mintt(T& t1, T t2) {
    t1=min(t1,t2);
}
#define MAX 100135

bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et(int x=-1) {
    printf("%d\n", x); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) { return y?gcd1(y,x%y):x;}

vector<pair<int, char>> mp[MAX];
char fac[MAX];
//string ins="";
map<string, int> mpc;
int strId,Ans[MAX], dfn[MAX];
vector<int> spos[MAX*2];
int qylr(int id, int l, int r) {
    if(r<l) return 0;
    return upper_bound(spos[id].begin(), spos[id].end(), r) - lower_bound(spos[id].begin(), spos[id].end(), l);
}
struct mb {
    int u,v,id;
    string x, rx="";
    void  rd(int i) {
        id=i;
        cin>>u>>v>>x;
        if (mpc.find(x)==mpc.end()) mpc[x]=++strId;
        for(int i=(int)x.size()-1;~i;i--) rx.push_back(x[i]);
        if (mpc.find(rx)==mpc.end()) mpc[rx]=++strId;
    }
}qs[MAX];
struct kmp {
    int nxt[200];
    void init(string &str) {
        int k=-1,j=0;
        nxt[0]=-1;
        int plen=(int)str.size();
        while (j<plen) {
            while (k!=-1&&str[k]!=str[j]) k=nxt[k];
            nxt[++j]=++k;
        }
    }
    int Kmp(string &s, string &p) {
        int j=0,k=0,ans=0,slen=(int)s.size(),plen=(int)p.size();
        while (j<slen) {
            while (k!=-1&&s[j]!=p[k]) k=nxt[k];
            j++; k++;
            if (k==plen) {ans++;k=nxt[k];}
        }
        return ans;
    }
}KP;
struct Hld {
    int fa[MAX],bigSon[MAX],sz[MAX],deep[MAX], fap[MAX][20];
    int head[MAX];
    int dfid=0;
    void calSize(int x, int pa, char fc) {
        sz[x]=1; fa[x]=pa; deep[x]=deep[pa]+1;
        fac[x]=fc;
        fap[x][0]=pa;

        int mx = 0;
        for(auto cp: mp[x]) if (cp.first!=pa) {
            int c=cp.first;
            calSize(c, x, cp.second);
            sz[x]+=sz[c];
            if (mx < sz[c]) {
                mx = sz[c]; bigSon[x]=c;
            }
        }
    }
    void init(){
        for(int j=1; (1<<j)<=n; j++)
            for(int i=1; i<=n; i++)
                fap[i][j]=fap[fap[i][j-1]][j-1];
    }

    void build(int x, int H) {
        head[x]=H; dfn[x]=++dfid;

        if (mp[x].size()==1) {//leaf
            //build sam
            vector<int> ins;
            for(int tmp=x; ; tmp=fa[tmp]) {
                ins.push_back(tmp);
                if (tmp==H) break;
            }
            reverse(ins.begin(), ins.end());

            int N=ins.size();
            REP(i, N) {
                string x="";
                for(int j=i;j<min(N,i+100);j++) {
                    x.push_back(fac[ins[j]]);
                    if (mpc.find(x) != mpc.end()) {
                        spos[mpc[x]].push_back(dfn[ins[i]]);
                    }
                }
            }

        }
        if (bigSon[x] != 0) build(bigSon[x], H);
        for(auto c:mp[x]) if (c.first!=fa[x] && c.first!=bigSon[x]) {
            build(c.first, c.first);
        }
    }
    int lca(int x, int y) {
        while (head[x] != head[y]) {
            if (deep[head[x]] < deep[head[y]]) {
                swap(x,y);
            }
            x = fa[head[x]];
        }
        return deep[x]<deep[y] ? x : y;
    }

    string apped;
    int TT=0;
    void up(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            TT+=qylr(sid, dfn[head[x]], dfn[x]-sn+1);
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }
                REP(j, apped.size()) if (S.size()==sn+sn-2) break;
                else S+=apped[j];

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);
        if (sn<=1) return;

        int tmp = x;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+sn-1) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]+sn-1) tmp=fa[tmp];
        if(ff==tmp) return;
        string S="";
        while(tmp != ff && S.size()<sn+sn-2) {
            S+=fac[tmp]; tmp=fa[tmp];
        }
        REP(j, apped.size()) if (S.size()==sn+sn-2) break;
        else S+=apped[j];

        reverse(S.begin(), S.end());
        TT+=KP.Kmp(S, s);

    }
    bool DB=false;
    void down(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            if (DB && deep[x]==128) {
                int tmp=x;
                while(1) {
                    cout<<dfn[tmp]<<" ";
                    if(tmp==H) break;
                    tmp=fa[tmp];
                }cout<<endl;
                //13320
                int id =mpc["qx"];
                cout<<spos[id].size()<<endl;
                for(int z: spos[id]) if (z<=dfn[x] && z>=dfn[H]) cout<<z<<" ";
                exit(0);
            }
            TT+=qylr(sid, dfn[head[x]], dfn[x]-(sn-1));
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);

    }

    void cal(int qid) {
        int x=qs[qid].u, y=qs[qid].v;
        if(x==y) return;
        int ff = lca(x, y);
        DB  =debug && qid==6730;
//        if (debug && qid==6730) {
//            cout<<ff<<endl;
//            int tmp=x;
//            while(tmp!=ff) {
//                cout<<fac[tmp]; tmp=fa[tmp];
//            }cout<<endl;
//            tmp=y;
//            while(tmp!=ff) {
//                cout<<fac[tmp]; tmp=fa[tmp];
//            }cout<<endl;
//            exit(0);
//        }
        apped="";
        int tmp = y;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+100) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]) {
            apped += fac[tmp]; tmp=fa[tmp];
        }
        reverse(apped.begin(), apped.end());
        TT=0;
        KP.init(qs[qid].rx);
        up(x,ff,qs[qid].rx, (int)qs[qid].rx.size(), mpc[qs[qid].rx]);
        KP.init(qs[qid].x);
        down(y,ff,qs[qid].x, (int)qs[qid].x.size(), mpc[qs[qid].x]);
        Ans[qs[qid].id] =TT;
        if (DB) exit(0);
    }
}ynk;
void fmain(int tid) {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    cin>>n;
    debug =0;

    REP(i,n-1) {
        int u,v; char c; cin>>u>>v>>c;
        mp[u].push_back({v,c});
        mp[v].push_back({u,c});
    }
    cin>>m;
    REQ(i,m) {
        qs[i].rd(i);
    }

    ynk.calSize(1, 0, ' ');
    ynk.build(1, 1);
    ynk.init();

    REQ(i,m) {
        ynk.cal(i);
        if (debug && i==6730) {
            cout<<qs[i].u<<" "<<qs[i].v<<" "<<qs[i].x;
            return;
        }
    }
    REQ(i,m) cout<<Ans[i]<<endl;
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD  1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef ll ValType;
template<typename  T> void maxtt(T& t1, T t2) {
    t1=max(t1,t2);
}
template<typename  T> void mintt(T& t1, T t2) {
    t1=min(t1,t2);
}
#define MAX 100035

bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et(int x=-1) {
    printf("%d\n", x); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) { return y?gcd1(y,x%y):x;}

vector<pair<int, char>> mp[MAX];
char fac[MAX];
//string ins="";
map<string, int> mpc;
int strId,Ans[MAX], dfn[MAX];
vector<int> spos[MAX*2];
int qylr(int id, int l, int r) {
    if(r<l) return 0;
    return upper_bound(spos[id].begin(), spos[id].end(), r) - lower_bound(spos[id].begin(), spos[id].end(), l);
}
struct mb {
    int u,v,id;
    string x, rx="";
    void  rd(int i) {
        id=i;
        cin>>u>>v>>x;
        if (mpc.find(x)==mpc.end()) mpc[x]=++strId;
        for(int i=(int)x.size()-1;~i;i--) rx.push_back(x[i]);
        if (mpc.find(rx)==mpc.end()) mpc[rx]=++strId;
    }
}qs[MAX];
struct kmp {
    int nxt[200];
    void init(string &str) {
        int k=-1,j=0;
        nxt[0]=-1;
        int plen=(int)str.size();
        while (j<plen) {
            while (k!=-1&&str[k]!=str[j]) k=nxt[k];
            nxt[++j]=++k;
        }
    }
    int Kmp(string &s, string &p) {
        int j=0,k=0,ans=0,slen=(int)s.size(),plen=(int)p.size();
        while (j<slen) {
            while (k!=-1&&s[j]!=p[k]) k=nxt[k];
            j++; k++;
            if (k==plen) {ans++;k=nxt[k];}
        }
        return ans;
    }
}KP;
struct Hld {
    int fa[MAX],bigSon[MAX],sz[MAX],deep[MAX], fap[MAX][20];
    int head[MAX];
    int dfid=0;
    void calSize(int x, int pa, char fc) {
        sz[x]=1; fa[x]=pa; deep[x]=deep[pa]+1;
        fac[x]=fc;
        fap[x][0]=pa;

        int mx = 0;
        for(auto cp: mp[x]) if (cp.first!=pa) {
            int c=cp.first;
            calSize(c, x, cp.second);
            sz[x]+=sz[c];
            if (mx < sz[c]) {
                mx = sz[c]; bigSon[x]=c;
            }
        }
    }
    void init(){
        for(int j=1; (1<<j)<=n; j++)
            for(int i=1; i<=n; i++)
                fap[i][j]=fap[fap[i][j-1]][j-1];
    }

    void build(int x, int H) {
        head[x]=H; dfn[x]=++dfid;

        if (mp[x].size()==1) {//leaf
            //build sam
            vector<int> ins;
            for(int tmp=x; ; tmp=fa[tmp]) {
                ins.push_back(tmp);
                if (tmp==H) break;
            }
            reverse(ins.begin(), ins.end());

            int N=ins.size();
            REP(i, N) {
                string x="";
                for(int j=i;j<min(N,i+100);j++) {
                    x.push_back(fac[ins[j]]);
                    if (mpc.find(x) != mpc.end()) {
                        spos[mpc[x]].push_back(dfn[ins[i]]);
                    }
                }
            }

        }
        if (bigSon[x] != 0) build(bigSon[x], H);
        for(auto c:mp[x]) if (c.first!=fa[x] && c.first!=bigSon[x]) {
            build(c.first, c.first);
        }
    }
    int lca(int x, int y) {
        while (head[x] != head[y]) {
            if (deep[head[x]] < deep[head[y]]) {
                swap(x,y);
            }
            x = fa[head[x]];
        }
        return deep[x]<deep[y] ? x : y;
    }

    string apped;
    int TT=0;
    void up(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            TT+=qylr(sid, dfn[head[x]], dfn[x]-sn+1);
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                int bfLen = deep[tmp]-deep[H]+1 + sn-1;

                string S="";
                while(tmp != ff && S.size()<bfLen) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }
                REP(j, apped.size()) if (S.size()==bfLen) break;
                else S+=apped[j];

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);
        if (sn<=1) return;

        int tmp = x;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+sn-1) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]+sn-1) tmp=fa[tmp];
        if(ff==tmp) return;
        int bfLen = deep[tmp]-deep[ff] + sn-1;
        string S="";
        while(tmp != ff && S.size()<bfLen) {
            S+=fac[tmp]; tmp=fa[tmp];
        }
        REP(j, apped.size()) if (S.size()==bfLen) break;
        else S+=apped[j];

        reverse(S.begin(), S.end());
        TT+=KP.Kmp(S, s);

    }
    bool DB=false;
    void down(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            if (DB && deep[x]==128) {
                int tmp=x;
                while(1) {
                    cout<<dfn[tmp]<<" ";
                    if(tmp==H) break;
                    tmp=fa[tmp];
                }cout<<endl;
                //13320
                int id =mpc["qx"];
                cout<<spos[id].size()<<endl;
                for(int z: spos[id]) if (z<=dfn[x] && z>=dfn[H]) cout<<z<<" ";
                exit(0);
            }
            TT+=qylr(sid, dfn[head[x]], dfn[x]-(sn-1));
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];
                int bfLen = deep[tmp]-deep[H]+1 + sn-1;
                string S="";
                while(tmp != ff && S.size()<bfLen) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);

    }

    void cal(int qid) {
        int x=qs[qid].u, y=qs[qid].v;
        if(x==y) return;
        int ff = lca(x, y);
//        DB  =debug && qid==10944;
//        if (DB) {
//            cout<<ff<<endl;
//            int tmp=x;
//            while(tmp!=ff) {
//                cout<<fac[tmp]; tmp=fa[tmp];
//            }cout<<endl;
//            tmp=y;
//            while(tmp!=ff) {
//                cout<<fac[tmp]; tmp=fa[tmp];
//            }cout<<endl;
//            exit(0);
//        }
        apped="";
        int tmp = y;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+100) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]) {
            apped += fac[tmp]; tmp=fa[tmp];
        }
        reverse(apped.begin(), apped.end());
        TT=0;
        KP.init(qs[qid].rx);
        up(x,ff,qs[qid].rx, (int)qs[qid].rx.size(), mpc[qs[qid].rx]);
        KP.init(qs[qid].x);
        down(y,ff,qs[qid].x, (int)qs[qid].x.size(), mpc[qs[qid].x]);
        Ans[qs[qid].id] =TT;
        if (DB) exit(0);
    }
}ynk;
void fmain(int tid) {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    cin>>n;
    debug =0;

    REP(i,n-1) {
        int u,v; char c; cin>>u>>v>>c;
        mp[u].push_back({v,c});
        mp[v].push_back({u,c});
    }
    cin>>m;
    REQ(i,m) {
        qs[i].rd(i);
    }

    ynk.calSize(1, 0, ' ');
    ynk.build(1, 1);
    ynk.init();

    REQ(i,m) {
        ynk.cal(i);
        if (debug && i==10944) {
            cout<<qs[i].u<<" "<<qs[i].v<<" "<<qs[i].x;
            return;
        }
    }
    REQ(i,m) cout<<Ans[i]<<endl;
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD  1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef ll ValType;
template<typename  T> void maxtt(T& t1, T t2) {
    t1=max(t1,t2);
}
template<typename  T> void mintt(T& t1, T t2) {
    t1=min(t1,t2);
}
#define MAX 100135

bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et(int x=-1) {
    printf("%d\n", x); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) { return y?gcd1(y,x%y):x;}

vector<pair<int, char>> mp[MAX];
char fac[MAX];
//string ins="";
map<string, int> mpc;
int strId,Ans[MAX], dfn[MAX];
vector<int> spos[MAX*2];
int qylr(int id, int l, int r) {
    if(r<l) return 0;
    return upper_bound(spos[id].begin(), spos[id].end(), r) - lower_bound(spos[id].begin(), spos[id].end(), l);
}
struct mb {
    int u,v,id;
    string x, rx="";
    void  rd(int i) {
        id=i;
        cin>>u>>v>>x;
        if (mpc.find(x)==mpc.end()) mpc[x]=++strId;
        for(int i=(int)x.size()-1;~i;i--) rx.push_back(x[i]);
        if (mpc.find(rx)==mpc.end()) mpc[rx]=++strId;
    }
}qs[MAX];
struct kmp {
    int nxt[200];
    void init(string &str) {
        int k=-1,j=0;
        nxt[0]=-1;
        int plen=(int)str.size();
        while (j<plen) {
            while (k!=-1&&str[k]!=str[j]) k=nxt[k];
            nxt[++j]=++k;
        }
    }
    int Kmp(string &s, string &p) {
        int j=0,k=0,ans=0,slen=(int)s.size(),plen=(int)p.size();
        while (j<slen) {
            while (k!=-1&&s[j]!=p[k]) k=nxt[k];
            j++; k++;
            if (k==plen) {ans++;k=nxt[k];}
        }
        return ans;
    }
}KP;
struct Hld {
    int fa[MAX],bigSon[MAX],sz[MAX],deep[MAX], fap[MAX][20];
    int head[MAX];
    int dfid=0;
    void calSize(int x, int pa, char fc) {
        sz[x]=1; fa[x]=pa; deep[x]=deep[pa]+1;
        fac[x]=fc;
        fap[x][0]=pa;

        int mx = 0;
        for(auto cp: mp[x]) if (cp.first!=pa) {
            int c=cp.first;
            calSize(c, x, cp.second);
            sz[x]+=sz[c];
            if (mx < sz[c]) {
                mx = sz[c]; bigSon[x]=c;
            }
        }
    }
    void init(){
        for(int j=1; (1<<j)<=n; j++)
            for(int i=1; i<=n; i++)
                fap[i][j]=fap[fap[i][j-1]][j-1];
    }

    void build(int x, int H) {
        head[x]=H; dfn[x]=++dfid;

        if (mp[x].size()==1) {//leaf
            //build sam
            vector<int> ins;
            for(int tmp=x; ; tmp=fa[tmp]) {
                ins.push_back(tmp);
                if (tmp==H) break;
            }
            reverse(ins.begin(), ins.end());

            int N=ins.size();
            REP(i, N) {
                string x="";
                for(int j=i;j<min(N,i+100);j++) {
                    x.push_back(fac[ins[j]]);
                    if (mpc.find(x) != mpc.end()) {
                        spos[mpc[x]].push_back(dfn[ins[j]]);
                    }
                }
            }

        }
        if (bigSon[x] != 0) build(bigSon[x], H);
        for(auto c:mp[x]) if (c.first!=fa[x] && c.first!=bigSon[x]) {
            build(c.first, c.first);
        }
    }
    int lca(int x, int y) {
        while (head[x] != head[y]) {
            if (deep[head[x]] < deep[head[y]]) {
                swap(x,y);
            }
            x = fa[head[x]];
        }
        return deep[x]<deep[y] ? x : y;
    }

    string apped;
    int TT=0;
    void up(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            TT+=qylr(sid, dfn[head[x]], dfn[x]-sn+1);
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }
                REP(j, apped.size()) if (S.size()==sn+sn-2) break;
                else S+=apped[j];

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);
        if (sn<=1) return;

        int tmp = x;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+sn-1) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]+sn-1) tmp=fa[tmp];
        if(ff==tmp) return;
        string S="";
        while(tmp != ff && S.size()<sn+sn-2) {
            S+=fac[tmp]; tmp=fa[tmp];
        }
        REP(j, apped.size()) if (S.size()==sn+sn-2) break;
        else S+=apped[j];

        reverse(S.begin(), S.end());
        TT+=KP.Kmp(S, s);

    }
    void down(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            TT+=qylr(sid, dfn[head[x]], dfn[x]-(sn-1));
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);

    }

    void cal(int qid) {
        int x=qs[qid].u, y=qs[qid].v;
        if(x==y) return;
        int ff = lca(x, y);
        apped="";
        int tmp = y;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+100) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]) {
            apped += fac[tmp]; tmp=fa[tmp];
        }
        reverse(apped.begin(), apped.end());
        TT=0;
        KP.init(qs[qid].rx);
        up(x,ff,qs[qid].rx, (int)qs[qid].rx.size(), mpc[qs[qid].rx]);
        KP.init(qs[qid].x);
        down(y,ff,qs[qid].x, (int)qs[qid].x.size(), mpc[qs[qid].x]);
        Ans[qs[qid].id] =TT;
    }
}ynk;
void fmain(int tid) {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    cin>>n;
    debug = n==50000;

    REP(i,n-1) {
        int u,v; char c; cin>>u>>v>>c;
        mp[u].push_back({v,c});
        mp[v].push_back({u,c});
    }
    cin>>m;
    REQ(i,m) {
        qs[i].rd(i);
    }

    ynk.calSize(1, 0, ' ');
    ynk.build(1, 1);
    ynk.init();

    REQ(i,m) {
        ynk.cal(i);
        if (debug && i==6730) {
            cout<<qs[i].u<<" "<<qs[i].v<<" "<<qs[i].x;
            return;
        }
    }
    REQ(i,m) cout<<Ans[i]<<endl;
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD  1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef ll ValType;
template<typename  T> void maxtt(T& t1, T t2) {
    t1=max(t1,t2);
}
template<typename  T> void mintt(T& t1, T t2) {
    t1=min(t1,t2);
}
#define MAX 100135

bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et(int x=-1) {
    printf("%d\n", x); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) { return y?gcd1(y,x%y):x;}

vector<pair<int, char>> mp[MAX];
char fac[MAX];
//string ins="";
map<string, int> mpc;
int strId,Ans[MAX], dfn[MAX];
vector<int> spos[MAX*2];
int qylr(int id, int l, int r) {
    if(r<l) return 0;
    return upper_bound(spos[id].begin(), spos[id].end(), r) - lower_bound(spos[id].begin(), spos[id].end(), l);
}
struct mb {
    int u,v,id;
    string x, rx="";
    void  rd(int i) {
        id=i;
        cin>>u>>v>>x;
        if (mpc.find(x)==mpc.end()) mpc[x]=++strId;
        for(int i=(int)x.size()-1;~i;i--) rx.push_back(x[i]);
        if (mpc.find(rx)==mpc.end()) mpc[rx]=++strId;
    }
}qs[MAX];
struct kmp {
    int nxt[200];
    void init(string &str) {
        int k=-1,j=0;
        nxt[0]=-1;
        int plen=(int)str.size();
        while (j<plen) {
            while (k!=-1&&str[k]!=str[j]) k=nxt[k];
            nxt[++j]=++k;
        }
    }
    int Kmp(string &s, string &p) {
        int j=0,k=0,ans=0,slen=(int)s.size(),plen=(int)p.size();
        while (j<slen) {
            while (k!=-1&&s[j]!=p[k]) k=nxt[k];
            j++; k++;
            if (k==plen) {ans++;k=nxt[k];}
        }
        return ans;
    }
}KP;
struct Hld {
    int fa[MAX],bigSon[MAX],sz[MAX],deep[MAX], fap[MAX][20];
    int head[MAX];
    int dfid=0;
    void calSize(int x, int pa, char fc) {
        sz[x]=1; fa[x]=pa; deep[x]=deep[pa]+1;
        fac[x]=fc;
        fap[x][0]=pa;

        int mx = 0;
        for(auto cp: mp[x]) if (cp.first!=pa) {
            int c=cp.first;
            calSize(c, x, cp.second);
            sz[x]+=sz[c];
            if (mx < sz[c]) {
                mx = sz[c]; bigSon[x]=c;
            }
        }
    }
    void init(){
        for(int j=1; (1<<j)<=n; j++)
            for(int i=1; i<=n; i++)
                fap[i][j]=fap[fap[i][j-1]][j-1];
    }

    void build(int x, int H) {
        head[x]=H; dfn[x]=++dfid;

        if (mp[x].size()==1) {//leaf
            //build sam
            vector<int> ins;
            for(int tmp=x; ; tmp=fa[tmp]) {
                ins.push_back(tmp);
                if (tmp==H) break;
            }
            reverse(ins.begin(), ins.end());

            int N=ins.size();
            REP(i, N) {
                string x="";
                for(int j=i;j<min(N,i+100);j++) {
                    x.push_back(fac[ins[j]]);
                    if (mpc.find(x) != mpc.end()) {
                        spos[mpc[x]].push_back(dfn[ins[j]]);
                    }
                }
            }

        }
        if (bigSon[x] != 0) build(bigSon[x], H);
        for(auto c:mp[x]) if (c.first!=fa[x] && c.first!=bigSon[x]) {
            build(c.first, c.first);
        }
    }
    int lca(int x, int y) {
        while (head[x] != head[y]) {
            if (deep[head[x]] < deep[head[y]]) {
                swap(x,y);
            }
            x = fa[head[x]];
        }
        return deep[x]<deep[y] ? x : y;
    }

    string apped;
    int TT=0;
    void up(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            TT+=qylr(sid, dfn[head[x]], dfn[x]-sn+1);
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }
                REP(j, apped.size()) if (S.size()==sn+sn-2) break;
                else S+=apped[j];

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);
        if (sn<=1) return;

        int tmp = x;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+sn-1) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]+sn-1) tmp=fa[tmp];
        if(ff==tmp) return;
        string S="";
        while(tmp != ff && S.size()<sn+sn-2) {
            S+=fac[tmp]; tmp=fa[tmp];
        }
        REP(j, apped.size()) if (S.size()==sn+sn-2) break;
        else S+=apped[j];

        reverse(S.begin(), S.end());
        TT+=KP.Kmp(S, s);

    }
    bool DB=false;
    void down(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            if (DB && deep[x]==128) {
                int tmp=x;
                while(1) {
                    cout<<fac[tmp]; if(tmp==H) break;
                    tmp=fa[tmp];
                }cout<<endl;
                cout<<mpc["qx"]<<endl;
                exit(0);
            }
            TT+=qylr(sid, dfn[head[x]], dfn[x]-(sn-1));
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);

    }

    void cal(int qid) {
        int x=qs[qid].u, y=qs[qid].v;
        if(x==y) return;
        int ff = lca(x, y);
        DB  =debug && qid==6730;
//        if (debug && qid==6730) {
//            cout<<ff<<endl;
//            int tmp=x;
//            while(tmp!=ff) {
//                cout<<fac[tmp]; tmp=fa[tmp];
//            }cout<<endl;
//            tmp=y;
//            while(tmp!=ff) {
//                cout<<fac[tmp]; tmp=fa[tmp];
//            }cout<<endl;
//            exit(0);
//        }
        apped="";
        int tmp = y;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+100) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]) {
            apped += fac[tmp]; tmp=fa[tmp];
        }
        reverse(apped.begin(), apped.end());
        TT=0;
        KP.init(qs[qid].rx);
        up(x,ff,qs[qid].rx, (int)qs[qid].rx.size(), mpc[qs[qid].rx]);
        KP.init(qs[qid].x);
        down(y,ff,qs[qid].x, (int)qs[qid].x.size(), mpc[qs[qid].x]);
        Ans[qs[qid].id] =TT;
        if (DB) exit(0);
    }
}ynk;
void fmain(int tid) {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    cin>>n;
    debug = n==50000;

    REP(i,n-1) {
        int u,v; char c; cin>>u>>v>>c;
        mp[u].push_back({v,c});
        mp[v].push_back({u,c});
    }
    cin>>m;
    REQ(i,m) {
        qs[i].rd(i);
    }

    ynk.calSize(1, 0, ' ');
    ynk.build(1, 1);
    ynk.init();

    REQ(i,m) {
        ynk.cal(i);
        if (debug && i==6730) {
            cout<<qs[i].u<<" "<<qs[i].v<<" "<<qs[i].x;
            return;
        }
    }
    REQ(i,m) cout<<Ans[i]<<endl;
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD  1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef ll ValType;
template<typename  T> void maxtt(T& t1, T t2) {
    t1=max(t1,t2);
}
template<typename  T> void mintt(T& t1, T t2) {
    t1=min(t1,t2);
}
#define MAX 100035

bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et(int x=-1) {
    printf("%d\n", x); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) { return y?gcd1(y,x%y):x;}

vector<pair<int, char>> mp[MAX];
char fac[MAX];
//string ins="";
map<string, int> mpc;
int strId,Ans[MAX], dfn[MAX];
vector<int> spos[MAX*2];
int qylr(int id, int l, int r) {
    if(r<l) return 0;
    return upper_bound(spos[id].begin(), spos[id].end(), r) - lower_bound(spos[id].begin(), spos[id].end(), l);
}
struct mb {
    int u,v,id;
    string x, rx="";
    void  rd(int i) {
        id=i;
        cin>>u>>v>>x;
        if (mpc.find(x)==mpc.end()) mpc[x]=++strId;
        for(int i=(int)x.size()-1;~i;i--) rx.push_back(x[i]);
        if (mpc.find(rx)==mpc.end()) mpc[rx]=++strId;
    }
}qs[MAX];
struct kmp {
    int nxt[200];
    void init(string &str) {
        int k=-1,j=0;
        nxt[0]=-1;
        int plen=(int)str.size();
        while (j<plen) {
            while (k!=-1&&str[k]!=str[j]) k=nxt[k];
            nxt[++j]=++k;
        }
    }
    int Kmp(string &s, string &p) {
        int j=0,k=0,ans=0,slen=(int)s.size(),plen=(int)p.size();
        while (j<slen) {
            while (k!=-1&&s[j]!=p[k]) k=nxt[k];
            j++; k++;
            if (k==plen) {ans++;k=nxt[k];}
        }
        return ans;
    }
}KP;
struct Hld {
    int fa[MAX],bigSon[MAX],sz[MAX],deep[MAX], fap[MAX][20];
    int head[MAX];
    int dfid=0;
    void calSize(int x, int pa, char fc) {
        sz[x]=1; fa[x]=pa; deep[x]=deep[pa]+1;
        fac[x]=fc;
        fap[x][0]=pa;

        int mx = 0;
        for(auto cp: mp[x]) if (cp.first!=pa) {
            int c=cp.first;
            calSize(c, x, cp.second);
            sz[x]+=sz[c];
            if (mx < sz[c]) {
                mx = sz[c]; bigSon[x]=c;
            }
        }
    }
    void init(){
        for(int j=1; (1<<j)<=n; j++)
            for(int i=1; i<=n; i++)
                fap[i][j]=fap[fap[i][j-1]][j-1];
    }

    void build(int x, int H) {
        head[x]=H; dfn[x]=++dfid;

        if (mp[x].size()==1) {//leaf
            //build sam
            vector<int> ins;
            for(int tmp=x; ; tmp=fa[tmp]) {
                ins.push_back(tmp);
                if (tmp==H) break;
            }
            reverse(ins.begin(), ins.end());

            int N=ins.size();
            REP(i, N) {
                string x="";
                for(int j=i;j<min(N,i+100);j++) {
                    x.push_back(fac[ins[j]]);
                    if (mpc.find(x) != mpc.end()) {
                        spos[mpc[x]].push_back(dfn[ins[i]]);
                    }
                }
            }

        }
        if (bigSon[x] != 0) build(bigSon[x], H);
        for(auto c:mp[x]) if (c.first!=fa[x] && c.first!=bigSon[x]) {
            build(c.first, c.first);
        }
    }
    int lca(int x, int y) {
        while (head[x] != head[y]) {
            if (deep[head[x]] < deep[head[y]]) {
                swap(x,y);
            }
            x = fa[head[x]];
        }
        return deep[x]<deep[y] ? x : y;
    }

    string apped;
    int TT=0;
    void up(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            TT+=qylr(sid, dfn[head[x]], dfn[x]-sn+1);
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }
                REP(j, apped.size()) if (S.size()==sn+sn-2) break;
                else S+=apped[j];

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);
        if (sn<=1) return;

        int tmp = x;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+sn-1) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]+sn-1) tmp=fa[tmp];
        if(ff==tmp) return;
        string S="";
        while(tmp != ff && S.size()<sn+sn-2) {
            S+=fac[tmp]; tmp=fa[tmp];
        }
        REP(j, apped.size()) if (S.size()==sn+sn-2) break;
        else S+=apped[j];

        reverse(S.begin(), S.end());
        TT+=KP.Kmp(S, s);

    }
    bool DB=false;
    void down(int x, int ff, string &s, int sn, int sid) {
        while(deep[head[x]]>deep[ff]) {
            int H=head[x];
            if (DB && deep[x]==128) {
                int tmp=x;
                while(1) {
                    cout<<dfn[tmp]<<" ";
                    if(tmp==H) break;
                    tmp=fa[tmp];
                }cout<<endl;
                //13320
                int id =mpc["qx"];
                cout<<spos[id].size()<<endl;
                for(int z: spos[id]) if (z<=dfn[x] && z>=dfn[H]) cout<<z<<" ";
                exit(0);
            }
            TT+=qylr(sid, dfn[head[x]], dfn[x]-(sn-1));
            if (sn!=1) {
                int tmp = x;
                for(int i=18;i>=0;i--) {
                    if (deep[fap[tmp][i]]>= deep[head[x]]+sn-2) tmp=fap[tmp][i];
                }
                while(deep[tmp]> deep[head[x]]+sn-2) tmp=fa[tmp];

                string S="";
                while(tmp != ff && S.size()<sn+sn-2) {
                    S+=fac[tmp]; tmp=fa[tmp];
                }

                reverse(S.begin(), S.end());
                TT+=KP.Kmp(S, s);
            }
            x=fa[H];
        }
        TT+=qylr(sid, dfn[ff]+1, dfn[x]-sn+1);

    }

    void cal(int qid) {
        int x=qs[qid].u, y=qs[qid].v;
        if(x==y) return;
        int ff = lca(x, y);
        DB  =debug && qid==10944;
        if (DB) {
            cout<<ff<<endl;
            int tmp=x;
            while(tmp!=ff) {
                cout<<fac[tmp]; tmp=fa[tmp];
            }cout<<endl;
            tmp=y;
            while(tmp!=ff) {
                cout<<fac[tmp]; tmp=fa[tmp];
            }cout<<endl;
            exit(0);
        }
        apped="";
        int tmp = y;
        for(int i=18;i>=0;i--) {
            if (deep[fap[tmp][i]]>= deep[ff]+100) tmp=fap[tmp][i];
        }
        while(deep[tmp]>deep[ff]) {
            apped += fac[tmp]; tmp=fa[tmp];
        }
        reverse(apped.begin(), apped.end());
        TT=0;
        KP.init(qs[qid].rx);
        up(x,ff,qs[qid].rx, (int)qs[qid].rx.size(), mpc[qs[qid].rx]);
        KP.init(qs[qid].x);
        down(y,ff,qs[qid].x, (int)qs[qid].x.size(), mpc[qs[qid].x]);
        Ans[qs[qid].id] =TT;
        if (DB) exit(0);
    }
}ynk;
void fmain(int tid) {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    cin>>n;
    debug = n==99900;

    REP(i,n-1) {
        int u,v; char c; cin>>u>>v>>c;
        mp[u].push_back({v,c});
        mp[v].push_back({u,c});
    }
    cin>>m;
    REQ(i,m) {
        qs[i].rd(i);
    }

    ynk.calSize(1, 0, ' ');
    ynk.build(1, 1);
    ynk.init();

    REQ(i,m) {
        ynk.cal(i);
        if (debug && i==10944) {
            cout<<qs[i].u<<" "<<qs[i].v<<" "<<qs[i].x;
            return;
        }
    }
    REQ(i,m) cout<<Ans[i]<<endl;
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}