```go
package main
import (
"fmt"
"io"
"os"
)
func main() {
data, err := io.ReadAll(os.Stdin)
if err != nil || len(data) == 0 {
return
}
ptr := 0
readInt := func() int {
for ptr < len(data) && (data[ptr] < '0' || data[ptr] > '9') {
ptr++
}
if ptr >= len(data) {
return 0
}
res := 0
for ptr < len(data) && data[ptr] >= '0' && data[ptr] <= '9' {
res = res*10 + int(data[ptr]-'0')
ptr++
}
return res
}
readWord := func() string {
for ptr < len(data) && data[ptr] <= ' ' {
ptr++
}
if ptr >= len(data) {
return ""
}
start := ptr
for ptr < len(data) && data[ptr] > ' ' {
ptr++
}
return string(data[start:ptr])
}
n := readInt()
m := readInt()
if n == 0 {
return
}
s := readWord()
adj := make([][]int, n)
inDegree := make([]int, n)
for i := 0; i < m; i++ {
u := readInt() - 1
v := readInt() - 1
adj[u] = append(adj[u], v)
inDegree[v]++
}
dp := make([][26]int32, n)
queue := make([]int, 0, n)
for i := 0; i < n; i++ {
if inDegree[i] == 0 {
queue = append(queue, i)
}
dp[i][s[i]-'a'] = 1
}
processed := 0
var ans int32 = 0
for len(queue) > 0 {
u := queue[0]
queue = queue[1:]
processed++
for c := 0; c < 26; c++ {
if dp[u][c] > ans {
ans = dp[u][c]
}
}
for _, v := range adj[u] {
charV := int(s[v] - 'a')
for c := 0; c < 26; c++ {
val := dp[u][c]
if c == charV {
val++
}
if val > dp[v][c] {
dp[v][c] = val
}
}
inDegree[v]--
if inDegree[v] == 0 {
queue = append(queue, v)
}
}
}
if processed < n {
fmt.Println("-1")
} else {
fmt.Println(ans)
}
}
```