#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
const int MAX_N = 3e5 + 10, MAX_LOG_N = 20;
const long long MOD1 = 1e9 + 7, BASE1 = 29, MOD2 = 1e9 + 9, BASE2 = 37;
long long sq(long long a, long long p) { return a * a % p; }
long long qpow(long long a, long long b, long long p) {
  return b ? sq(qpow(a, b / 2, p), p) * (b & 1 ? a : 1) % p : 1;
}
long long inv(long long a, long long p) { return qpow(a, p - 2, p); }
int N, M, logN, log_table[MAX_N], pa[MAX_N], jmp[MAX_N][MAX_LOG_N],
    depth[MAX_N], down_len[MAX_N], chain_content[MAX_N * 2],
    *chain_content_alloc = chain_content, *pos[MAX_N];
char S[MAX_N];
long long pow_base1[MAX_N], pow_base1i[MAX_N], pow_base2[MAX_N],
    pow_base2i[MAX_N];
long long pref_hash1_up[MAX_N], pref_hash1_down[MAX_N], pref_hash2_up[MAX_N],
    pref_hash2_down[MAX_N];
vector<int> edge[MAX_N], child[MAX_N];
void construct_dfs1(int x) {
  pref_hash1_down[x] =
      (pref_hash1_down[pa[x]] + (S[x] - 'a') * pow_base1[depth[x]]) % MOD1;
  pref_hash1_up[x] =
      (pref_hash1_up[pa[x]] + (S[x] - 'a') * pow_base1i[depth[x]]) % MOD1;
  pref_hash2_down[x] =
      (pref_hash2_down[pa[x]] + (S[x] - 'a') * pow_base2[depth[x]]) % MOD2;
  pref_hash2_up[x] =
      (pref_hash2_up[pa[x]] + (S[x] - 'a') * pow_base2i[depth[x]]) % MOD2;
  for (int i : edge[x]) {
    if (i == pa[x]) continue;
    child[x].push_back(i);
    pa[i] = x;
    depth[i] = depth[x] + 1;
    construct_dfs1(i);
    down_len[x] = max(down_len[x], down_len[i]);
  }
  down_len[x]++;
  sort(child[x].begin(), child[x].end(),
       [](int a, int b) { return down_len[a] > down_len[b]; });
}
void construct_dfs2(int x) {
  vector<int> light;
  int y = x;
  while (!child[y].empty()) {
    for (int i = 1; i < child[y].size(); i++) light.push_back(child[y][i]);
    y = child[y][0];
  }
  chain_content_alloc += 2 * down_len[x];
  int *t = chain_content_alloc;
  for (int i = 1; i <= 2 * down_len[x]; i++) {
    *--t = y;
    if (i <= down_len[x]) {
      pos[y] = t;
    }
    y = pa[y];
  }
  for (int i : light) {
    construct_dfs2(i);
  }
}
void init() {
  scanf("%d", &N);
  for (int i = 1; i <= N; i++) {
    log_table[i] = log_table[i - 1];
    if (1 << log_table[i] + 1 < i) log_table[i]++;
  }
  logN = log_table[N];
  pow_base1[0] = pow_base1i[0] = pow_base2[0] = pow_base2i[0] = 1;
  pow_base1[1] = BASE1;
  pow_base1i[1] = inv(BASE1, MOD1);
  pow_base2[1] = BASE2;
  pow_base2i[1] = inv(BASE2, MOD2);
  for (long long *arr : {pow_base1, pow_base1i}) {
    for (int i = 2; i <= N; i++) arr[i] = arr[1] * arr[i - 1] % MOD1;
  }
  for (long long *arr : {pow_base2, pow_base2i}) {
    for (int i = 2; i <= N; i++) arr[i] = arr[1] * arr[i - 1] % MOD2;
  }
  scanf("%s", S + 1);
  for (int i = 1; i < N; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    edge[a].push_back(b);
    edge[b].push_back(a);
  }
  construct_dfs1(1);
  for (int i = 1; i <= N; i++) jmp[i][0] = pa[i];
  for (int i = 1; i <= logN; i++) {
    for (int j = 1; j <= N; j++) {
      jmp[j][i] = jmp[jmp[j][i - 1]][i - 1];
    }
  }
  construct_dfs2(1);
}
int kth_ancestor(int x, int k) {
  if (k) {
    int t = log_table[k];
    x = jmp[x][t];
    k -= 1 << t;
  }
  return pos[x][-k];
}
int LCA(int a, int b) {
  if (depth[a] > depth[b]) swap(a, b);
  b = kth_ancestor(b, depth[b] - depth[a]);
  if (a == b) return a;
  for (int i = logN; i >= 0; i--) {
    if (jmp[a][i] != jmp[b][i]) {
      a = jmp[a][i];
      b = jmp[b][i];
    }
  }
  return pa[a];
}
long long hash1_up(int a, int b) {
  return (pref_hash1_up[a] - pref_hash1_up[pa[b]] + MOD1) *
         pow_base1[depth[a]] % MOD1;
}
long long hash1_down(int a, int b) {
  return (pref_hash1_down[a] - pref_hash1_down[pa[b]] + MOD1) *
         pow_base1i[depth[b]] % MOD1;
}
long long hash1(int a, int b, int c, int len) {
  if (len <= depth[a] - depth[b] + 1) {
    return hash1_up(a, kth_ancestor(a, len - 1));
  } else {
    int dis = depth[a] + depth[c] - 2 * depth[b] + 1;
    long long res =
        hash1_up(a, b) + hash1_down(kth_ancestor(c, dis - len),
                                    kth_ancestor(c, depth[c] - depth[b] - 1)) *
                             pow_base1[depth[a] - depth[b] + 1];
    return res % MOD1;
  }
}
long long hash2_up(int a, int b) {
  return (pref_hash2_up[a] - pref_hash2_up[pa[b]] + MOD2) *
         pow_base2[depth[a]] % MOD2;
}
long long hash2_down(int a, int b) {
  return (pref_hash2_down[a] - pref_hash2_down[pa[b]] + MOD2) *
         pow_base2i[depth[b]] % MOD2;
}
long long hash2(int a, int b, int c, int len) {
  if (len <= depth[a] - depth[b] + 1) {
    return hash2_up(a, kth_ancestor(a, len - 1));
  } else {
    int dis = depth[a] + depth[c] - 2 * depth[b] + 1;
    long long res =
        hash2_up(a, b) + hash2_down(kth_ancestor(c, dis - len),
                                    kth_ancestor(c, depth[c] - depth[b] - 1)) *
                             pow_base2[depth[a] - depth[b] + 1];
    return res % MOD2;
  }
}
void solve() {
  int s1, t1, s2, t2;
  scanf("%d%d%d%d", &s1, &t1, &s2, &t2);
  int c1 = LCA(s1, t1), c2 = LCA(s2, t2);
  int l = 0, r = min(depth[s1] + depth[t1] - 2 * depth[c1] + 1,
                     depth[s2] + depth[t2] - 2 * depth[c2] + 1);
  while (l != r) {
    int m = (l + r + 1) / 2;
    if (hash1(s1, c1, t1, m) == hash1(s2, c2, t2, m) &&
        hash2(s1, c1, t1, m) == hash2(s2, c2, t2, m)) {
      l = m;
    } else {
      r = m - 1;
    }
  }
  printf("%d\n", l);
}
int main() {
  init();
  scanf("%d", &M);
  for (int i = 1; i <= M; i++) {
    solve();
  }
}
