#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>
#include <functional>
#include <vector>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <cassert>
#define InfL 1000000000
#define InfLL 1000000000000000000LL
#define nmax_def 220000
#define mod 1000000007
#define rep(i,n) for(int (i)=0;(i)<(n);(i)++)
#define rrep(i,n) for(int (i)=(n-1);(i)>=(0);(i)--)
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<bool> vb;
typedef vector<db> vd;
typedef struct {
	ll koma_num;
	ll dist_sum_min; // できる限り相殺する
	ll dist_sum_max; // 相殺しない
}DP_struct;

class Graph_class {
public:
	bool graph_from1 = true;
	bool graph_tree = true;
	bool graph_weight = false;
	bool graph_digraph = false;
	int Vnum;
	int Enum;
	string S;
	vector<pii> edgelist;
	vl edgeweight;
	vector<vi> adjlist;
	vector<vl> adjlistweight;
	vi adjnum;

	vi adj_to_root;
	vector<DP_struct> DP;
	vi vlist_from_root;
	vl xdist;

	vb x_visited;
	deque<int> x_que;

	vi branch_type;


	void read_edge();
	void adjini();
	void visited_ini();
	void graph_BFS(ll BFS_ini);
	void ReRooting(ll root);
	void solve();

	bool xydist_def = false;
};

// ----- graph -----

void Graph_class::read_edge() {
	cin >> Vnum;
	if (graph_tree)
		Enum = Vnum - 1;// graph
	else
		cin >> Enum;
	edgelist.resize(Enum);
	edgeweight.resize(Enum, 1);
	cin >> S;
	rep(i, Enum) {
		if (graph_weight)
			cin >> edgelist[i].first >> edgelist[i].second >> edgeweight[i];
		else
			cin >> edgelist[i].first >> edgelist[i].second;
		if (graph_from1) {
			edgelist[i].first--;
			edgelist[i].second--;
		}
	}
	return;
}

void Graph_class::adjini() {
	branch_type.resize(Vnum);
	adjnum.resize(Vnum);
	xdist.resize(Vnum, -1);
	adjlist.resize(Vnum);
	if (graph_weight)
		adjlistweight.resize(Vnum);
	adj_to_root.resize(Vnum, -1);
	DP.resize(Vnum);
	rep(i, Vnum)
		adjnum[i] = 0;
	rep(i, Enum) {
		int x = edgelist[i].first;
		int y = edgelist[i].second;
		adjlist[x].push_back(y);
		if (!graph_digraph)
			adjlist[y].push_back(x);
		if (graph_weight) {
			ll xyweight = edgeweight[i];
			adjlistweight[x].push_back(xyweight);
			if (!graph_digraph)
				adjlistweight[y].push_back(xyweight);
		}
		adjnum[x]++;
		if (!graph_digraph)
			adjnum[y]++;
	}
	x_visited.resize(Vnum);
	visited_ini();

	return;
}

void Graph_class::visited_ini() {
	rep(i, Vnum) {
		branch_type[i] = -1;
		x_visited[i] = false;
		adj_to_root[i] = -1;
	}
	x_que.clear();
}

void Graph_class::graph_BFS(ll BFS_ini) {
	visited_ini();
	x_que.push_back(BFS_ini);
	x_visited[BFS_ini] = true;

	// option
	xdist[BFS_ini] = 0;
	vlist_from_root.clear();
	vlist_from_root.push_back(BFS_ini);
	//cout << BFS_ini << endl;
	rep(i, adjnum[BFS_ini]) {
		int x_new = adjlist[BFS_ini][i];
		branch_type[x_new] = i;
	}

	while (!x_que.empty()) {
		int x = x_que.front();
		x_que.pop_front();
		rep(i, adjnum[x]) {
			int x_new = adjlist[x][i];
			int dist_new = 1;
			if (graph_weight)
				dist_new = adjlistweight[x][i];
			if (!x_visited[x_new]) {
				x_visited[x_new] = true;
				x_que.push_back(x_new);

				// option
				adj_to_root[x_new] = x;
				vlist_from_root.push_back(x_new);
				xdist[x_new] = xdist[x] + dist_new;
				if (x != BFS_ini)
					branch_type[x_new] = branch_type[x];
				//cout << x_new << endl;
			}
		}
	}
	return;
}

void Graph_class::ReRooting(ll root) {
	rep(i, Vnum) {
		DP[i].dist_sum_min = 0;
		DP[i].dist_sum_max = 0;
		DP[i].koma_num = 0;
	}
	graph_BFS(root);
	rrep(i, Vnum) { // 根から遠い点から見る
		ll x = vlist_from_root[i];
		vl xdist_min_array(adjnum[x], InfLL);
		vl xdist_max_array(adjnum[x], -InfLL);
		ll xdist_min_sum = 0;
		ll xdist_max_sum = 0;
		rep(j, adjnum[x]) {
			ll x_new = adjlist[x][j];
			if (x_new == adj_to_root[x]) // 根側の頂点の場合は処理しない
				continue;
			xdist_min_array[j] = DP[x_new].dist_sum_min + DP[x_new].koma_num; // 根に1回近づくと、コマの数だけ距離が伸びる
			xdist_max_array[j] = DP[x_new].dist_sum_max + DP[x_new].koma_num; // 根に1回近づくと、コマの数だけ距離が伸びる
			xdist_min_sum += xdist_min_array[j];
			xdist_max_sum += xdist_max_array[j];
			DP[x].koma_num += DP[x_new].koma_num;
		}

		DP[x].dist_sum_max = xdist_max_sum; // 最大化するには足すだけ
		ll dist_sum_min = 0;
		rep(j, adjnum[x]) {
			ll x_new = adjlist[x][j];
			if (x_new == adj_to_root[x]) // 根側の頂点の場合は処理しない
				continue;
			ll dist_sum_min_tmp = max(xdist_min_sum % 2LL, xdist_min_array[j] - (xdist_max_sum - xdist_max_array[j])); // 最小化するには、ある1つの枝は最小化、他は最大化して相殺して三角不等式を満たせばよい
			 // 距離の合計の偶奇は変更不可なので最小値に注意
			dist_sum_min = max(dist_sum_min, dist_sum_min_tmp);
		}
		DP[x].dist_sum_min = dist_sum_min;
		if (S[x] == '1')
			DP[x].koma_num++;
	}
	return;
}

void Graph_class::solve() {
	ll ans = InfLL;
	ll onesum = 0;
	rep(i, Vnum) {
		if (S[i] == '1')
			onesum++;
	}
	rep(BFS_ini, Vnum) {
		graph_BFS(BFS_ini);
		ReRooting(BFS_ini);
		assert(DP[BFS_ini].koma_num == onesum);
		if (DP[BFS_ini].dist_sum_min == 0) { // 根で距離の相殺が完了していればOK
			ll anstmp = 0;
			rep(xtmp, Vnum) {
				if (S[xtmp] == '0')
					continue;
				anstmp += xdist[xtmp];
			}
			anstmp /= 2;
			ans = min(ans, anstmp);
		}
	}
	if (ans == InfLL)
		ans = -1;
	cout << ans << endl;
	return;
}

int main(void) {
	Graph_class graph;
	graph.read_edge();
	graph.adjini();
	graph.solve();
	return 0;
}

Measured memory_bytes: 512