#include <bits/stdc++.h>
using namespace std;
const int maxn = 300100 * 2;
struct Tnode {
  Tnode *son[26];
} node[maxn], *root[maxn];
int tot;
int sz[maxn], fa[maxn], a[maxn], n;
char ch[maxn];
vector<int> edge[maxn];
void init() {
  memset(node, 0, sizeof(node));
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  scanf("%s", ch + 1);
  for (int i = 1; i < n; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    edge[x].push_back(y);
    edge[y].push_back(x);
  }
}
int dfsx(Tnode *p) {
  int tot = 1;
  for (int x = 0; x < 26; x++)
    if (p->son[x]) tot += dfsx(p->son[x]);
  return tot;
}
void merge(int x, char nw, Tnode *f, Tnode *s) {
  if (!f->son[nw - 'a']) {
    f->son[nw - 'a'] = s;
    sz[x] += dfsx(s);
  } else {
    for (int i = 0; i < 26; i++)
      if (s->son[i]) merge(x, i + 'a', f->son[nw - 'a'], s->son[i]);
  }
}
void dfs(int x, int fa) {
  for (auto p : edge[x])
    if (p != fa) dfs(p, x);
  root[x] = &node[++tot];
  sz[x] = 1;
  int mx = 0, mxi = 0;
  for (auto p : edge[x])
    if (p != fa)
      if (sz[p] > mx) mx = sz[p], mxi = p;
  if (!mx) {
    a[x]++;
    return;
  }
  sz[x] += mx;
  root[x]->son[ch[mxi] - 'a'] = root[mxi];
  for (auto p : edge[x])
    if (p != fa && p != mxi) merge(x, ch[p], root[x], root[p]);
  a[x] += sz[x];
}
int main() {
  init();
  dfs(1, 1);
  int x = 0, y = 0;
  for (int i = 1; i <= n; i++) {
    if (a[i] > y) y = a[i];
  }
  cout << y << endl;
  for (int i = 1; i <= n; i++)
    if (a[i] == y) x++;
  cout << x << endl;
  return 0;
}
