#include <bits/stdc++.h>
int read() {
  int ret = 0;
  char c = getchar();
  while (c < '0' || c > '9') c = getchar();
  while (c >= '0' && c <= '9') {
    ret = ret * 10 + c - '0';
    c = getchar();
  }
  return ret;
}
const int MAXN = 300000;
const int MAXLEN = (MAXN << 2);
const int MAXLOG = 20;
int LOG[MAXLEN + 10];
int S[MAXLEN + 10];
int cnt;
int A[2][MAXLEN + 10];
int order[MAXLEN + 10], ordern[MAXLEN + 10];
void work(int first) {
  static int num[MAXLEN + 10];
  int UP = 0, zero = 0;
  for (int i = 1; i <= cnt; i++)
    UP = ((UP) > (A[first][i]) ? (UP) : (A[first][i]));
  for (int i = 0; i <= UP; i++) num[i] = 0;
  for (int i = 1; i <= cnt; i++) num[A[first][i]]++;
  for (int i = 1; i <= UP; i++) num[i] += num[i - 1];
  for (int i = 1; i <= cnt; i++)
    if (A[first][order[i]] == 0)
      ordern[++zero] = order[i];
    else
      ordern[++num[A[first][order[i]] - 1]] = order[i];
  for (int i = 1; i <= cnt; i++) order[i] = ordern[i];
  return;
}
int rank[MAXLEN + 10], sa[MAXLEN + 10];
int height[MAXLEN + 10];
int MIN[MAXLOG + 10][MAXLEN + 10];
void build_height() {
  S[cnt + 1] = -1;
  for (int i = 1; i <= cnt; i++) {
    int p = ((height[rank[i - 1]] - 1) > (0) ? (height[rank[i - 1]] - 1) : (0));
    int id = rank[i];
    while (S[i + p] == S[sa[id + 1] + p]) p++;
    height[id] = p;
  }
  for (int i = 1; i <= cnt; i++) MIN[0][i] = height[i];
  for (int i = 1; (1 << i) <= cnt; i++)
    for (int j = 1; j <= cnt; j++)
      MIN[i][j] = ((MIN[i - 1][j]) < (MIN[i - 1][j + (1 << (i - 1))])
                       ? (MIN[i - 1][j])
                       : (MIN[i - 1][j + (1 << (i - 1))]));
  for (int i = 1, nxt = 1, a = -1; i <= cnt; i++) {
    if (i == nxt) {
      nxt <<= 1;
      ++a;
    }
    LOG[i] = a;
  }
  return;
}
int getlcp(int first, int second) {
  if (second == first) return cnt;
  first = rank[first], second = rank[second];
  if (first > second) std::swap(first, second);
  int k = LOG[second - first];
  return ((MIN[k][first]) < (MIN[k][second - (1 << k)])
              ? (MIN[k][first])
              : (MIN[k][second - (1 << k)]));
}
void suffix_array() {
  for (int i = 1; i <= cnt; i++) rank[i] = S[i];
  int ln = 0, len = 1;
  while (ln < cnt) {
    for (int i = 1; i <= cnt; i++) A[0][i] = rank[i], order[i] = i;
    for (int i = 1; i <= cnt; i++)
      A[1][i] = (i + len <= cnt) ? (rank[i + len]) : (0);
    for (int j = 1; j >= 0; j--) work(j);
    ln = 0;
    for (int i = 1; i <= cnt; i++) {
      rank[order[i]] = ++ln;
      int j = i;
      while (j < cnt && A[0][order[i]] == A[0][order[j + 1]] &&
             A[1][order[i]] == A[1][order[j + 1]])
        rank[order[++j]] = ln;
      i = j;
    }
    len <<= 1;
  }
  for (int i = 1; i <= cnt; i++) sa[rank[i]] = i;
  build_height();
  return;
}
int n, m;
char q[MAXN + 10];
std::pair<int, int> front[(MAXN << 1) + 10];
int orderx[(MAXN << 1) + 10], stdx[MAXN + 10];
void sortx() {
  static int num[MAXN + 10];
  memset(num, 0, sizeof(num));
  for (int i = 1; i <= m; i++) num[front[i].first]++;
  for (int i = 1; i <= n; i++) stdx[i] = num[i] += num[i - 1];
  for (int i = 1; i <= m; i++) orderx[++num[front[i].first - 1]] = i;
  return;
}
int line[MAXN + 10];
int fa[MAXN + 10], dep[MAXN + 10], sz[MAXN + 10], maxs[MAXN + 10];
int FA[MAXLOG + 10][MAXN + 10];
int upstep(int first, int step) {
  while (step) {
    first = FA[LOG[step]][first];
    step -= (1 << LOG[step]);
  }
  return first;
}
void bfs() {
  int l, r;
  line[l = r = 0] = 1;
  for (; l <= r; l++) {
    int first = line[l];
    sz[first] = 1;
    for (int j = 1; FA[j - 1][first]; j++)
      FA[j][first] = FA[j - 1][FA[j - 1][first]];
    for (int i = stdx[first - 1] + 1; i <= stdx[first]; i++) {
      int next = front[orderx[i]].second;
      if (next != fa[first]) {
        FA[0][next] = fa[next] = first;
        dep[next] = dep[first] + 1;
        line[++r] = next;
      }
    }
  }
  for (; r; r--) {
    int first = line[r];
    sz[fa[first]] += sz[first];
    if (sz[maxs[fa[first]]] < sz[first]) maxs[fa[first]] = first;
  }
  return;
}
int top[MAXN + 10];
int pos[2][MAXN + 10];
void dfs(int pre, int first) {
  S[++cnt] = q[first] - 'a' + 1;
  pos[0][first] = cnt;
  if (maxs[first]) {
    top[maxs[first]] = top[first];
    dfs(first, maxs[first]);
  }
  for (int i = stdx[first - 1] + 1; i <= stdx[first]; i++) {
    int next = front[orderx[i]].second;
    if (next != pre && next != maxs[first]) {
      S[++cnt] = 30;
      top[next] = next;
      dfs(first, next);
    }
  }
  return;
}
struct STACK {
  int id, len, ward;
} stack[2][MAXN + 10], stan[MAXN + 10];
int Qs[2], Qt[2];
int tp[2], stp;
void get(int id) {
  tp[id] = stp = 0;
  int s = Qs[id], t = Qt[id];
  while (top[s] != top[t]) {
    if (dep[top[s]] > dep[top[t]]) {
      stack[id][++tp[id]] = (STACK){s, dep[s] - dep[fa[top[s]]], 1};
      s = fa[top[s]];
    } else {
      stan[++stp] = (STACK){top[t], dep[t] - dep[fa[top[t]]], 0};
      t = fa[top[t]];
    }
  }
  if (dep[s] < dep[t])
    stack[id][++tp[id]] = (STACK){s, dep[t] - dep[s] + 1, 0};
  else
    stack[id][++tp[id]] = (STACK){s, dep[s] - dep[t] + 1, 1};
  while (stp) stack[id][++tp[id]] = stan[stp--];
  stack[id][++tp[id]] = (STACK){Qt[id], 0, 0};
  return;
}
int query() {
  int ret = 0;
  get(0);
  get(1);
  int ln[2];
  ln[0] = ln[1] = 1;
  while (ln[0] < tp[0] && ln[1] < tp[1]) {
    int nxt = getlcp(pos[stack[0][ln[0]].ward][stack[0][ln[0]].id],
                     pos[stack[1][ln[1]].ward][stack[1][ln[1]].id]);
    nxt =
        ((((nxt) < (stack[0][ln[0]].len) ? (nxt) : (stack[0][ln[0]].len))) <
                 (stack[1][ln[1]].len)
             ? (((nxt) < (stack[0][ln[0]].len) ? (nxt) : (stack[0][ln[0]].len)))
             : (stack[1][ln[1]].len));
    ret += nxt;
    stack[0][ln[0]].len -= nxt;
    stack[1][ln[1]].len -= nxt;
    bool con = false;
    if (stack[0][ln[0]].len == 0 || stack[1][ln[1]].len == 0) {
      if (stack[0][ln[0]].len == 0)
        ln[0]++;
      else if (stack[0][ln[0]].ward == 1)
        stack[0][ln[0]].id = upstep(stack[0][ln[0]].id, nxt);
      else
        stack[0][ln[0]].id =
            upstep(stack[0][ln[0] + 1].id, dep[stack[0][ln[0] + 1].id] -
                                               (dep[stack[0][ln[0]].id] + nxt));
      if (stack[1][ln[1]].len == 0)
        ln[1]++;
      else if (stack[1][ln[1]].ward == 1)
        stack[1][ln[1]].id = upstep(stack[1][ln[1]].id, nxt);
      else
        stack[1][ln[1]].id =
            upstep(stack[1][ln[1] + 1].id, dep[stack[1][ln[1] + 1].id] -
                                               (dep[stack[1][ln[1]].id] + nxt));
    } else
      return ret;
  }
  return ret;
}
void init() {
  n = read();
  for (int i = 1; i <= n; i++) {
    char c = getchar();
    while (c < 'a' || c > 'z') c = getchar();
    q[i] = c;
  }
  for (int i = 1; i < n; i++) {
    int first = read(), second = read();
    front[++m] = std::make_pair(first, second);
    front[++m] = std::make_pair(second, first);
  }
  sortx();
  bfs();
  top[1] = 1;
  dfs(-1, 1);
  for (int i = 1; i <= n; i++) pos[1][i] = (cnt << 1) - pos[0][i] + 2;
  for (int i = 1; i <= cnt; i++) S[(cnt << 1) - i + 2] = S[i];
  S[cnt + 1] = 30;
  cnt = (cnt << 1) + 1;
  suffix_array();
  int q = read();
  while (q--) {
    Qs[0] = read();
    Qt[0] = read();
    Qs[1] = read();
    Qt[1] = read();
    printf("%d\n", query());
  }
  return;
}
int main() {
  init();
  return 0;
}
