#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <limits>
#include <numeric>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#pragma comment(linker, "/STACK:36777216")

using namespace std;

#define MP make_pair
#define all(v) (v).begin(), (v).end()
#define PROBLEM_ID "A"

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<bool> vb;
typedef long double ld;
typedef pair<int, int> pii;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<vvl> vvvl;
typedef pair<ll, ll> pll;

const int INF = 1000000000;

int MinCompress(const vvi& G, const string& s, int root, vb& done, vi& children_cnt, vi& dist_to_children, vi& min_dist_to_children) {
  done[root] = true;
  vi children;
  for (int i = 0; i < G[root].size(); ++i) {
    int other = G[root][i];
    if (done[other]) {
      continue;
    }
    children.push_back(other);
    MinCompress(G, s, other, done, children_cnt, dist_to_children, min_dist_to_children);
  }
  children_cnt[root] = 0;
  if (s[root] == '1') {
    ++children_cnt[root];
  }
  min_dist_to_children[root] = 0;
  int sum_dists = 0;
  int max_dist = 0;
  for (int i = 0; i < children.size(); ++i) {
    int child = children[i];
    children_cnt[root] += children_cnt[child];    
    int cur_dist = dist_to_children[child] + children_cnt[child];
    dist_to_children[root] += cur_dist;
    sum_dists += cur_dist;
    int cur_min_dist = children_cnt[child] + min_dist_to_children[child];    
    if (cur_min_dist > max_dist) {
      max_dist = cur_min_dist;
    }
  }  
  int res = 0;
  bool found_big_child = false;
  for (int i = 0; i < children.size(); ++i) {
    int child = children[i];
    if (children_cnt[child] + min_dist_to_children[child] > sum_dists - children_cnt[child] - dist_to_children[child]) {
      found_big_child = true;
      res = sum_dists - children_cnt[child] - dist_to_children[child];
      min_dist_to_children[root] = children_cnt[child] + min_dist_to_children[child] - (sum_dists - children_cnt[child] - dist_to_children[child]);
      break;
    }
  }
  if (!found_big_child) {
    res += sum_dists / 2;
    min_dist_to_children[root] = sum_dists % 2;
  }
  return res;
}

int MinCompleteCompress(const vvi& G, const string& s, int n) {
  int res = INF;
  for (int i = 0; i < n; ++i) {
    vi children_cnt(n, 0);
    vi dist_to_children(n, 0);
    vi min_dist_to_children(n, 0);
    vb done(n, false);
    int x = MinCompress(G, s, i, done, children_cnt, dist_to_children, min_dist_to_children);
    if (min_dist_to_children[i] == 0 && x < res) {
      res = x;
    }
  }
  
  return res;
}

void DefineParentsAndDepth(const vvi& G, int a, int parent, int d, vi& p, vi& depth) {
  p[a] = parent;
  depth[a] = d;
  for (int i = 0; i < G[a].size(); ++i) {
    int other = G[a][i];
    if (other == parent) {
      continue;
    }
    DefineParentsAndDepth(G, other, a, d + 1, p, depth);
  }
}

bool IsGood(const vi& cnt) {
  int nonzero = 0;
  for (int i = 0; i < cnt.size(); ++i) {
    if (cnt[i] != 0) {
      ++nonzero;
    }
  }
  return nonzero <= 1;
}

int MinCompleteCompressStupid(const vvi& G, const string& s, int n) {
  vi cnt(n, 0);
  for (int i = 0; i < n; ++i) {
    cnt[i] = s[i] - '0';
  }
  vi p(n, -1);
  vi depth(n, -1);
  DefineParentsAndDepth(G, 0, -1, 0, p, depth);
  int res = 0;
  queue<vi> q;
  q.push(cnt);
  map<vi, int> d;
  map<vi, vi> prev;
  d[cnt] = 0;
  if (IsGood(cnt)) {
    return 0;
  }
  while (!q.empty()) {
    cnt = q.front();
    q.pop();
    for (int a = 0; a < n; ++a) {
      if (cnt[a] == 0) {
        continue;
      }
      for (int b = a + 1; b < n; ++b) {
        if (cnt[b] == 0) {
          continue;
        }
        vi path_a;
        path_a.push_back(a);
        vi path_b;
        path_b.push_back(b);
        int aa = a;
        int bb = b;
        while (depth[aa] > depth[bb]) {
          aa = p[aa];
          path_a.push_back(aa);
        }
        while (depth[bb] > depth[aa]) {
          bb = p[bb];
          path_b.push_back(bb);
        }
        while (aa != bb) {
          aa = p[aa];
          bb = p[bb];
          path_a.push_back(aa);
          path_b.push_back(bb);
        }
        vi path = path_a;
        for (int i = (int)path_b.size() - 2; i >= 0; --i) {
          path.push_back(path_b[i]);
        }
        if (path.size() - 1 >= 2) {
          vi ncnt = cnt;
          ncnt[path[1]] += 1;
          ncnt[path[0]] -= 1;
          ncnt[path[path.size() - 2]] += 1;
          ncnt[path.back()] -= 1;
          if (!d.count(ncnt)) {
            d[ncnt] = d[cnt] + 1;
            if (IsGood(ncnt)) {
              return d[ncnt];
            }
            prev[ncnt] = cnt;
            q.push(ncnt);
          }
        }
      }
    }
  }
  return INF;
}

int main() {
  /*while (true) {
    int n = rand() % 15 + 1;
    cerr << n << endl;
    vi p(n, -1);
    for (int i = 1; i < n; ++i) {
      p[i] = rand() % i;
    }
    vi order;
    for (int i = 0; i < n; ++i) {
      order.push_back(i);
    }
    random_shuffle(order.begin(), order.end());
    vvi G(n);
    for (int i = 1; i < n; ++i) {
      G[order[p[i]]].push_back(order[i]);
      G[order[i]].push_back(order[p[i]]);
    }
    string s;
    for (int i = 0; i < n; ++i) {
      s += ('0' + rand() % 2);
    }
    int res1 = MinCompleteCompress(G, s, n);
    int res2 = MinCompleteCompressStupid(G, s, n);
    if (res1 != res2) {
      cerr << "Wrong answer: " << res1 << ' ' << res2 << endl;
      cerr << n << endl;
      cerr << s << endl;
      for (int i = 0; i < G.size(); ++i) {
        for (int j = 0; j < G[i].size(); ++j) {
          if (i < G[i][j]) {
            cerr << i + 1 << ' ' << G[i][j] + 1 << endl;
          }
        }
      }
      break;
    }
    else {
      cerr << "OK " << res1 << endl;
    }
  }*/
  int n;
  cin >> n;
  string s;
  cin >> s;
  vvi G(n);
  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);
  }
  int res = MinCompleteCompress(G, s, n);
  if (res == INF) {
    cout << -1 << endl;
  }
  else {
    cout << res << endl;
  }
  return 0;
}


Measured memory_bytes: 768