```go
package main
import (
"io"
"os"
)
func main() {
buffer, _ := io.ReadAll(os.Stdin)
pos := 0
readInt := func() int {
for pos < len(buffer) && (buffer[pos] < '0' || buffer[pos] > '9') {
pos++
}
if pos >= len(buffer) {
return 0
}
res := 0
for pos < len(buffer) && buffer[pos] >= '0' && buffer[pos] <= '9' {
res = res*10 + int(buffer[pos]-'0')
pos++
}
return res
}
n := readInt()
if n == 0 {
return
}
head := make([]int, n+1)
next := make([]int, 2*n)
to := make([]int, 2*n)
edgeCount := 1
addEdge := func(u, v int) {
to[edgeCount] = v
next[edgeCount] = head[u]
head[u] = edgeCount
edgeCount++
}
for i := 0; i < n-1; i++ {
u := readInt()
v := readInt()
addEdge(u, v)
addEdge(v, u)
}
parent := make([]int, n+1)
order := make([]int, 0, n)
order = append(order, 1)
visited := make([]bool, n+1)
visited[1] = true
headQueue := 0
for headQueue < len(order) {
u := order[headQueue]
headQueue++
for e := head[u]; e != 0; e = next[e] {
v := to[e]
if !visited[v] {
visited[v] = true
parent[v] = u
order = append(order, v)
}
}
}
g := make([]int, n+1)
for i := n - 1; i >= 0; i-- {
u := order[i]
for e := head[u]; e != 0; e = next[e] {
v := to[e]
if v != parent[u] {
g[u] ^= (g[v] + 1)
}
}
}
inH := make([]bool, n+1)
inH[1] = true
ans := make([]byte, n)
X := g[1]
for k := 1; k <= n; k++ {
curr := k
for !inH[curr] {
inH[curr] = true
X ^= g[curr] ^ (g[curr] + 1) ^ 1
curr = parent[curr]
}
if X != 0 {
ans[k-1] = '1'
} else {
ans[k-1] = '2'
}
}
os.Stdout.Write(ans)
os.Stdout.Write([]byte{'\n'})
}
```