#include <bits/stdc++.h>
using namespace std;
int n;
vector<int> c;
string s;
vector<vector<int>> tree;
struct TrieNode {
  int size = 1;
  TrieNode* child[26] = {nullptr};
};
void pull_size(TrieNode* node) {
  node->size = 1;
  for (int i = 0; i < 26; ++i) {
    if (node->child[i] != nullptr) {
      node->size += node->child[i]->size;
    }
  }
}
TrieNode* merge(TrieNode* n1, TrieNode* n2) {
  if (n1 == nullptr) return n2;
  if (n2 == nullptr) return n1;
  if (n1->size > n2->size) {
    swap(n1, n2);
  }
  for (int i = 0; i < 26; ++i) n1->child[i] = merge(n1->child[i], n2->child[i]);
  delete n2;
  pull_size(n1);
  return n1;
}
TrieNode* dfs(int node, int parent) {
  TrieNode* here = new TrieNode;
  for (int child : tree[node]) {
    if (child != parent) {
      here->child[s[child] - 'a'] =
          merge(here->child[s[child] - 'a'], dfs(child, node));
    }
  }
  pull_size(here);
  c[node] += here->size;
  return here;
}
int main() {
  ios_base::sync_with_stdio(false), cin.tie(NULL);
  cin >> n;
  c = vector<int>(n);
  for (int i = 0; i < n; ++i) cin >> c[i];
  cin >> s;
  tree = vector<vector<int>>(n);
  for (int i = 0; i < n - 1; ++i) {
    int u, v;
    cin >> u >> v;
    --u, --v;
    tree[u].push_back(v);
    tree[v].push_back(u);
  }
  dfs(0, 0);
  int mx = *max_element(c.begin(), c.end());
  int cnt = 0;
  for (auto i : c) cnt += (i == mx);
  cout << mx << endl << cnt << endl;
}
