#include <cstdio>
#include <cctype>
#include <cstring>

namespace quick {
#define tp template<typename Type>
	namespace in {
		inline char getc() {
			static char buf[1<<21],*p1=buf,*p2=buf;
			return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;
		}
		inline int read(char *s) {
			*s=getc();
			while(isspace(*s)) {*s=getc();if(*s==EOF) return 0;}
			while(!isspace(*s)&&*s!=EOF) {s++;*s=getc();}
			*s='\0'; return 1;
		}
		tp inline int read(Type &x) {
			x=0;bool k=false;char c=getc();
			while(!isdigit(c)) {k|=(c=='-');c=getc();if(c==EOF) return 0;}
			while(isdigit(c)) {x=(x<<1)+(x<<3)+(c^48);c=getc();}
			x*=(k?-1:1); return 1;
		}
		template <typename Type,typename... Args>
		inline int read(const Type &t,const Args &...args) {
			return read(const_cast<Type&>(t))+read(const_cast<Args&>(args)...);
		}
	}
	using in::read;
	namespace out {
		char buf[1<<21];int p1=-1;const int p2=(1<<21)-1;
		inline void flush() {
			fwrite(buf,1,p1+1,stdout);
			p1=-1;
		}
		inline void putc(const char &c) {
			if(p1==p2) flush();
			buf[++p1]=c;
		}
		inline void write(char *s) {
			while(*s!='\0') putc(*s),s++;
		}
		inline void write(const char *s) {
			while(*s!='\0') putc(*s),s++;
		}
		tp inline void write(Type x) {
			static char buf[30];int p=-1;
			if(x<0) {putc('-');x=-x;}
			if(x==0) putc('0');
			else for(;x;x/=10) buf[++p]=x%10+48;
			for(;p!=-1;p--) putc(buf[p]);
		}
		inline void write(const char &c) {putc(c);}
		template <typename Type,typename... Args>
		inline void write(Type t,Args ...args) {
			write(t);write(args...);
		}
	}
	using out::write;
	using out::flush;
	tp inline Type max(const Type &a,const Type &b) {
		if(a<b) return b;
		return a;
	}
	tp inline Type min(const Type &a,const Type &b) {
		if(a<b) return a;
		return b;
	}
	tp inline void swap(Type &a,Type &b) {
		a^=b^=a^=b;
	}
	tp inline Type abs(const Type &a) {
		return a>=0?a:-a;
	}
#undef tp
}
using namespace quick;

typedef long long ll;
const ll Inf=0x3f3f3f3f3f3f3f3f;
const int maxn=2000+10,inf=0x3f3f3f3f;
int n;
char s[maxn];

struct Edge {
	int v,next;
	Edge(const int &v,const int &next) :v(v),next(next) {}
	Edge() {}
}e[maxn<<1];
int head[maxn],k;
inline void AddEdge(const int &u,const int &v) {
	e[++k]=Edge(v,head[u]);
	head[u]=k;
}

ll f[maxn];//表示以i为根的子树所消除的个数
ll sum[maxn];//表示以i为根的子树中dist(u,v)之和,其中u为当前节点，v为子树中有棋子的点
int cnt[maxn];
void dfs(const int &u,const int &fa) {
	int maxp=0;cnt[u]=s[u]-'0';
	for(int i(head[u]);i;i=e[i].next) {
		const int &v=e[i].v;
		if(v==fa) continue;
		dfs(v,u);
		cnt[u]+=cnt[v];
		sum[u]+=(sum[v]+=cnt[v]);//因为sum[maxp]要和sum[u]比大小，或者说当前转化为从u出发。所以要加上cnt[v]
		if(sum[v]>sum[maxp]) maxp=v;
	}
	if(!maxp) return;
	if(sum[u]>=2*sum[maxp]) f[u]=sum[u]/2;
	else f[u]=sum[u]-sum[maxp]+min(f[maxp],(2*sum[maxp]-sum[u])/2);
}

int main(void) {
#ifndef ONLINE_JUDGE
	freopen("cc.in","r",stdin);
#endif
	read(n,s+1);
	for(int i(1);i<n;i++) {
		int u,v;
		read(u,v);
		AddEdge(u,v);
		AddEdge(v,u);
	}
	ll ans=Inf;
	for(int i(1);i<=n;i++) {
		memset(f,0,sizeof f);
		memset(sum,0,sizeof sum);
		dfs(i,0);
		if(!(sum[i]&1)&&f[i]*2==sum[i]) ans=min(ans,f[i]);
	}
	if(ans==Inf) ans=-1;
	write(ans,'\n');
	flush();
	return 0;
}


Measured memory_bytes: 1748