#include <bits/stdc++.h>
using namespace std;
const int inf = int(1e9);
const double eps = 1e-4;
const double pi = 4 * atan(double(1));
const int N = int(3e5) + 100;
const int M = int(1e6) + 100;
const int sizes[] = {3600, 60, 1, -1};
const int MOD1 = int(1e9) + 7;
const int X1 = 4243;
struct _hash {
  int a;
  _hash() {}
  _hash(int a) : a(a) {}
};
_hash operator+(const _hash& a, const _hash& b) {
  _hash c(a.a + b.a);
  if (c.a >= MOD1) {
    c.a -= MOD1;
  }
  return c;
}
_hash operator-(const _hash& a, const _hash& b) {
  _hash c(a.a - b.a);
  if (c.a < 0) {
    c.a += MOD1;
  }
  return c;
}
_hash operator*(const _hash& a, const _hash& b) {
  return _hash((1LL * a.a * b.a) % MOD1);
}
bool operator==(const _hash& a, const _hash& b) { return a.a == b.a; }
struct tq {
  int a, b, ab, c, d, cd;
};
struct node {
  int val;
  node** _next;
};
const _hash X(X1);
int n;
int h[N], _prev[N], _rank[N], val[N], p[N];
bool used[N];
_hash st[N], rev_st[N];
_hash pw[2 * N];
vector<pair<int, int*> > lca[N];
node* ver[N];
vector<int> g[N];
tq q[M];
char s[N];
int get(int a) {
  if (_prev[a] != a) {
    _prev[a] = get(_prev[a]);
  }
  return _prev[a];
}
inline void merge(int a, int b, int c) {
  a = get(a);
  b = get(b);
  if (_rank[a] < _rank[b]) {
    swap(a, b);
  }
  _prev[b] = a;
  if (_rank[a] == _rank[b]) {
    ++_rank[a];
  }
  val[a] = c;
}
inline node* clone(node* v, int lev) {
  node* res = new node();
  res->val = v->val;
  if (sizes[lev] != -1) {
    int cnt =
        max(((lev == 0 ? n : sizes[lev - 1]) + sizes[lev] - 1) / sizes[lev], 1);
    res->_next = new node*[cnt];
    for (int i = 0; i < cnt; ++i) {
      res->_next[i] = v->_next[i];
    }
  }
  return res;
}
node* set_val(node* v, int lev, int pos, int val) {
  v = clone(v, lev);
  if (sizes[lev] == -1) {
    v->val = val;
    return v;
  }
  v->_next[pos / sizes[lev]] =
      set_val(v->_next[pos / sizes[lev]], lev + 1, pos % sizes[lev], val);
  return v;
}
int get_val(node* v, int pos) {
  int lev = 0;
  while (sizes[lev] != -1) {
    v = v->_next[pos / sizes[lev]];
    pos %= sizes[lev];
    ++lev;
  }
  return v->val;
}
void dfs(int v, int pv, node* cur) {
  used[v] = true;
  p[v] = pv;
  if (pv != -1) {
    g[v].erase(find((g[v]).begin(), (g[v]).end(), pv));
    h[v] = h[pv] + 1;
  } else {
    h[v] = 0;
  }
  cur = set_val(cur, 0, h[v], v);
  ver[v] = cur;
  st[v] = (pv == -1 ? _hash(0) : st[pv]) + pw[h[v]] * _hash(s[v]);
  rev_st[v] = (pv == -1 ? _hash(0) : rev_st[pv]) + pw[n - h[v]] * _hash(s[v]);
  for (int i = 0; i < int((lca[v]).size()); ++i) {
    if (used[lca[v][i].first]) {
      *(lca[v][i].second) = val[get(lca[v][i].first)];
    }
  }
  for (int i = 0; i < int((g[v]).size()); ++i) {
    dfs(g[v][i], v, cur);
    merge(g[v][i], v, v);
  }
}
inline int len(int a, int b, int ab) { return h[a] + h[b] - 2 * h[ab] + 1; }
inline _hash get(int v, int lca) {
  return (rev_st[v] - (p[lca] == -1 ? _hash(0) : rev_st[p[lca]])) * pw[h[v]];
}
inline int get_ver(int v, int len) {
  len = h[v] - len + 1;
  return get_val(ver[v], len);
}
inline _hash get_hash(int a, int b, int ab, int len) {
  int first = h[a] - h[ab] + 1;
  if (len <= first) {
    return get(a, get_ver(a, len));
  }
  len -= first;
  int ver = get_ver(b, h[b] - h[ab] + 1 - len);
  return get(a, ab) + (st[ver] - st[ab]) * pw[n + first - (h[ab] + 1)];
}
int main() {
  scanf("%d", &n);
  gets(s);
  gets(s);
  for (int i = 0; i < n - 1; ++i) {
    int a, b;
    scanf("%d %d", &a, &b);
    --a;
    --b;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  pw[0] = _hash(1);
  for (int i = 1; i <= 2 * n; ++i) {
    pw[i] = pw[i - 1] * X;
  }
  int m;
  scanf("%d", &m);
  for (int i = 0; i < m; ++i) {
    scanf("%d %d %d %d", &q[i].a, &q[i].b, &q[i].c, &q[i].d);
    --q[i].a;
    --q[i].b;
    --q[i].c;
    --q[i].d;
    lca[q[i].a].push_back(make_pair(q[i].b, &q[i].ab));
    lca[q[i].b].push_back(make_pair(q[i].a, &q[i].ab));
    lca[q[i].c].push_back(make_pair(q[i].d, &q[i].cd));
    lca[q[i].d].push_back(make_pair(q[i].c, &q[i].cd));
  }
  for (int i = 0; i < n; ++i) {
    _prev[i] = i;
    _rank[i] = 1;
    val[i] = i;
  }
  int root = 0;
  node* vers = new node[100];
  int lev;
  for (lev = 0; sizes[lev] != -1; ++lev) {
    vers[lev]._next = new node*[max(
        ((lev == 0 ? n : sizes[lev - 1]) + sizes[lev] - 1) / sizes[lev], 1)];
  }
  for (--lev; lev >= 0; --lev) {
    for (int j = 0; j < max(((lev == 0 ? n : sizes[lev - 1]) + sizes[lev] - 1) /
                                sizes[lev],
                            1);
         ++j) {
      vers[lev]._next[j] = &vers[lev + 1];
    }
  }
  dfs(root, -1, &vers[0]);
  for (int i = 0; i < m; ++i) {
    int ans = 0, l = 1,
        r = min(len(q[i].a, q[i].b, q[i].ab), len(q[i].c, q[i].d, q[i].cd));
    while (l <= r) {
      int mid = (l + r) / 2;
      _hash h1 = get_hash(q[i].a, q[i].b, q[i].ab, mid);
      _hash h2 = get_hash(q[i].c, q[i].d, q[i].cd, mid);
      if (h1 == h2) {
        ans = mid;
        l = mid + 1;
      } else {
        r = mid - 1;
      }
    }
    printf("%d\n", ans);
  }
  return 0;
}
