//{{{
#include<algorithm>
#include<cmath>
#include<fstream>
#include<iomanip>
#include<iostream>
#include<map>
#include<numeric>
#include<queue>
#include<random>
#include<set>
#include<sstream>
#include<sys/time.h>
#include<unordered_map>
#include<unordered_set>
#include<vector>
using ll = long long;
enum : int { M = (int)1e9 + 7 };
enum : ll { MLL = (ll)1e18L + 9 };
using namespace std;
#ifdef LOCAL
#include"rprint2.hpp"
#else
#define FUNC(name) template <ostream& out = cout, class... T> void name(T&&...){ }
FUNC(prints) FUNC(printw) FUNC(printwe) FUNC(printb) FUNC(printbe) FUNC(printd) FUNC(printde) FUNC(printdu);
#endif
template <class S, class T>
istream& operator >> (istream& in, pair<S, T>& p){ return in >> p.first >> p.second; }
template <class T>
istream& operator >> (istream& in, vector<T>& v){ for(auto& e : v){ in >> e; } return in; }
//}}}

struct Elem {
    int acc = 0, mini = 0, num = 0;
    bool operator < (const Elem& e) const {
        return pair<int, int>(acc, mini) < pair<int, int>(e.acc, e.mini);
        // return tie(acc, mini, num) < tie(e.acc, e.mini, e.num);
    }
};

struct Graph{
    struct Node{
        vector<int> dests;
        int num;
    };
    vector<Node> nodes;
    Graph(int num): nodes(num){ }
    int id(Node* n){ return n - &nodes[0]; }
    int id(Node& n){ return &n - &nodes[0]; }
    void print(){ for(auto& node : nodes){ prints(id(node), node.dests); } }
    void add1Edge(int from, int dest){
        nodes[from].dests.push_back(dest);
    }
    void add2Edge2(int from, int dest){
        add1Edge(from, dest);
        add1Edge(dest, from);
    }
    Elem dfs(int idx, int from){
        Elem ret = {};
        // vector<Elem> nums;
        Elem maxi = {-1, -1, -1};
        for(int didx : nodes[idx].dests){
            if(didx == from){ continue; }
            auto r = dfs(didx, idx);
            // nums.push_back(r);
            ret.acc += r.acc;
            ret.num += r.num;
            maxi = max(maxi, r);
        }
        if(maxi.acc == -1){
        // if(nums.empty()){
            return {nodes[idx].num, nodes[idx].num, nodes[idx].num};
        }
        // sort(nums.begin(), nums.end());
        ret.mini = ret.num + nodes[idx].num;
        ret.mini += max(ret.acc % 2, maxi.mini - (ret.acc -maxi.acc + 0 - 0));
        // ret.mini += max(ret.acc % 2, nums.back().mini - (ret.acc -nums.back().acc + 0 - 0));
        ret.num += nodes[idx].num;
        ret.acc += ret.num;
        return ret;
    }
};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    Graph g(n);
    string s; cin >> s;
    for(int i = 0; i < n - 1; i++){
        int a, b;
        cin >> a >> b;
        a--; b--;
        g.add2Edge2(a, b);
    }
    ll ans = MLL;
    for(int i = 0; i < n; i++){
        g.nodes[i].num = s[i] - '0';
    }
    for(int i = 0; i < n; i++){
        Elem maxi = {-1, -1, -1};
        ll acc = 0;
        // vector<Elem> nums;
        for(auto& didx : g.nodes[i].dests){
            auto e = g.dfs(didx, i);
            maxi = max(maxi, e);
            acc += e.acc;
            // nums.push_back(g.dfs(didx, i));
        }
        // sort(nums.begin(), nums.end());
        // for(auto& e : nums){
        //     acc += e.acc;
        // }
        // if(i == 1){
        //     printde(acc);
        //     for(auto& e : nums){
        //         printde(e.acc, e.mini, e.num);
        //     }
        // }
        if(acc % 2 == 0 && acc - maxi.acc >= maxi.mini){
        // if(acc % 2 == 0 && acc - nums.back().acc >= nums.back().mini){
            ans = min(ans, acc / 2);
        }
    }
    cout << (ans == MLL ? -1 : ans) << '\n';
}


Measured memory_bytes: 888