data class Edge(val from: Int, val to: Int)

fun main(args: Array<String>) {
  val n = readLine()!!.toInt()
  val labels = readLine()!!
  val graph = Array(n, { mutableListOf<Edge>() })
  repeat(n - 1) {
    val (v1Raw, v2Raw) = readLine()!!.split(" ").map(String::toInt)
    val v1 = v1Raw - 1
    val v2 = v2Raw - 1
    graph[v1].add(Edge(v1, v2))
    graph[v2].add(Edge(v2, v1))
  }

  fun solveForRoot(r: Int): Int? {
    val dpCount = IntArray(n, { -1 })
    val dpMin = IntArray(n, { -1 })
    val dpMax = IntArray(n, { -1 })

    fun dfs(v: Int, prev: Int) {
      val children = graph[v].filter { it.to != prev }.map { it.to }
      if (children.isEmpty()) {
        // Leaf
        dpCount[v] = if (labels[v] == '1') 1 else 0
        dpMin[v] = 0
        dpMax[v] = 0
      } else {
        children.forEach { dfs(it, v) }

        val maxSum = children.sumBy { dpMax[it] + dpCount[it] }
        val maxRemaining = children
            .map { Math.max(dpMin[it] + dpCount[it] - (maxSum - dpMax[it] - dpCount[it]), 0) }
            .max()!!
        if (maxRemaining == 0) {
          dpCount[v] = children.sumBy { dpCount[it] } + if (labels[v] == '1') 1 else 0
          dpMin[v] = maxSum % 2
          dpMax[v] = maxSum
        } else {
          dpCount[v] = children.sumBy { dpCount[it] } + if (labels[v] == '1') 1 else 0
          dpMin[v] = maxRemaining
          dpMax[v] = maxSum
        }
      }
    }

    dfs(r, -1)
    val ans = if (dpMin[r] == 0) dpMax[r] / 2 else null
    return ans
  }

  val ans = (0 until n).map(::solveForRoot).filterNotNull().min() ?: -1
  println(ans)
}
