#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
int n, q, sa[N * 2], rnk[N * 2], tp[N * 2], buc[N * 4], st[20][N * 2],
    lg[N * 2];
int cnt, idx, head[N], d[N], fa[N], sz[N], son[N], top[N], dfn[N];
char ch[N], s[N * 2];
struct edge {
  int v, nxt;
} e[N * 2];
struct node {
  int l, r;
} stk[2][2][N];
void add(int u, int v) {
  e[++cnt] = (edge){v, head[u]};
  head[u] = cnt;
}
void getsa(int n, int m = 128) {
  for (int i = (1); i <= (n); i++) buc[rnk[i] = s[i]]++;
  for (int i = (1); i <= (m); i++) buc[i] += buc[i - 1];
  for (int i = (n); i >= (1); i--) sa[buc[rnk[i]]--] = i;
  for (int k = 1, p; memset(buc, p = 0, m * 4 + 4); k <<= 1) {
    for (int i = (n - k + 1); i <= (n); i++) tp[++p] = i;
    for (int i = (1); i <= (n); i++)
      if (sa[i] > k) tp[++p] = sa[i] - k;
    for (int i = (1); i <= (n); i++) buc[rnk[i]]++;
    for (int i = (1); i <= (m); i++) buc[i] += buc[i - 1];
    for (int i = (n); i >= (1); i--) sa[buc[rnk[tp[i]]]--] = tp[i];
    p = 0, memcpy(tp, rnk, n * 4 + 4);
    for (int i = (1); i <= (n); i++)
      rnk[sa[i]] = p +=
          tp[sa[i]] ^ tp[sa[i - 1]] || tp[sa[i] + k] ^ tp[sa[i - 1] + k];
    if ((m = p) >= n) break;
  }
  int k = 0;
  for (int i = (1); i <= (n); i++) {
    for (k ? k-- : 0; s[i + k] == s[sa[rnk[i] - 1] + k]; k++)
      ;
    st[0][rnk[i]] = k;
  }
  for (int i = (1); i <= (19); i++)
    for (int j = (1); j <= (n - (1 << i) + 1); j++)
      st[i][j] = min(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
}
int lcp(int a, int b) {
  if (a == b) return n - a + 1;
  a = rnk[a], b = rnk[b];
  if (a > b) swap(a, b);
  int t = lg[b - a];
  return min(st[t][a + 1], st[t][b - (1 << t) + 1]);
}
void dfs1(int u) {
  d[u] = d[fa[u]] + (sz[u] = 1);
  for (int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].v;
    if (v == fa[u]) continue;
    fa[v] = u, dfs1(v);
    sz[u] += sz[v];
    if (sz[v] > sz[son[u]]) son[u] = v;
  }
}
void dfs2(int u, int tp) {
  top[u] = tp, s[dfn[u] = ++idx] = ch[u];
  if (son[u]) dfs2(son[u], tp);
  for (int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].v;
    if (v != fa[u] && v != son[u]) dfs2(v, v);
  }
}
void cal(int u, int tu, int ty, node& res) {
  if (ty)
    res.l = tu, res.r = u;
  else
    res.l = n + 1 - u, res.r = n + 1 - tu;
}
void getstr(int u, int v, int t[], int id) {
  int du = t[0] = t[1] = 0;
  for (; top[u] != top[v]; u = fa[top[u]]) {
    if (d[top[u]] < d[top[v]]) swap(u, v), du ^= 1;
    cal(dfn[u], dfn[top[u]], du, stk[id][du][++t[du]]);
  }
  if (d[u] < d[v]) swap(u, v), du ^= 1;
  cal(dfn[u], dfn[v], du, stk[id][du][++t[du]]);
  while (t[1]) stk[id][0][++t[0]] = stk[id][1][t[1]--];
}
int main() {
  scanf("%d%s", &n, ch + 1);
  for (int i = (2); i <= (n); i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    add(u, v), add(v, u);
  }
  dfs1(1), dfs2(1, 1);
  reverse_copy(s + 1, s + n + 1, s + n + 2);
  getsa(n = n * 2 + 1);
  for (int i = (2); i <= (n); i++) lg[i] = lg[i >> 1] + 1;
  scanf("%d", &q);
  while (q--) {
    int a, b, c, d, t[2][2], ans = 0;
    scanf("%d%d%d%d", &a, &b, &c, &d);
    getstr(a, b, t[0], 0), getstr(c, d, t[1], 1);
    for (int i = 1, j = 1; i <= t[0][0] && j <= t[1][0];) {
      node* s[2] = {&stk[0][0][i], &stk[1][0][j]};
      int LCP = lcp(s[0]->l, s[1]->l),
          d = s[1]->r - s[1]->l < s[0]->r - s[0]->l;
      if (LCP < s[d]->r - s[d]->l + 1) {
        ans += LCP;
        break;
      } else
        ans += LCP = s[d]->r - s[d]->l + 1, s[!d]->l += LCP, d ? j++ : i++;
    }
    printf("%d\n", ans);
  }
  return 0;
}
