#include <bits/stdc++.h>
using namespace std;
vector<vector<int> > adj(300001), subtree(300001);
int T[300001][26], c[300001], a[300001], h[300001], subtreeSize[300001],
    heavyChild[300001], subtreeNo[300001], nextIndex, cnt, ans, ansv;
string s;
int GetStringNo(int i, char c) {
  int j = c - 'a';
  if (T[i][j] == 0) T[i][j] = ++nextIndex;
  return T[i][j];
}
void Initialise(int n) {
  for (int i = 1; i <= n; i++) {
    heavyChild[i] = i;
    subtreeNo[i] = i;
  }
}
void HeavyLightDFS(int i, int p) {
  a[i] = GetStringNo(a[p], s[i - 1]);
  for (auto k : adj[i]) {
    if (k == p) continue;
    HeavyLightDFS(k, i);
    heavyChild[i] =
        (subtreeSize[k] > subtreeSize[heavyChild[i]]) ? k : heavyChild[i];
    subtreeSize[i] += subtreeSize[k];
  }
  subtreeNo[i] = subtreeNo[heavyChild[i]];
  subtreeSize[i]++;
}
void ResetBag(int i) {
  for (auto x : subtree[i]) h[a[x]] = 0;
  cnt = 0;
}
void Update(int i) {
  h[a[i]]++;
  cnt += (h[a[i]] == 1);
}
void CopyLightChild(int root, int child) {
  for (auto k : subtree[child]) {
    subtree[root].push_back(k);
    Update(k);
  }
}
void DFS(int i, int p) {
  for (auto k : adj[i]) {
    if (k != p && k != heavyChild[i]) {
      DFS(k, i);
      ResetBag(subtreeNo[k]);
    }
  }
  if (heavyChild[i] != i) DFS(heavyChild[i], i);
  for (auto k : adj[i]) {
    if (k != p && k != heavyChild[i]) {
      CopyLightChild(subtreeNo[i], subtreeNo[k]);
    }
  }
  Update(i);
  subtree[subtreeNo[i]].push_back(i);
  c[i] += cnt;
  if (c[i] == ans)
    ansv++;
  else if (c[i] > ans)
    ans = c[i], ansv = 1;
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) scanf("%d", &c[i]);
  cin >> s;
  for (int k = 1; k < n; k++) {
    int i, j;
    scanf("%d%d", &i, &j);
    adj[i].push_back(j);
    adj[j].push_back(i);
  }
  Initialise(n);
  HeavyLightDFS(1, 0);
  DFS(1, 0);
  printf("%d\n%d\n", ans, ansv);
  return 0;
}
