/*
给定一张有向图,图上每个结点都有一个字符,现在要求出一条路径,要使路径上某字符出现的次数最多
如果有环,输出-1即可
拓扑排序+dp
dp[i][26]表示排序到结点i时26个字符出现的次数
在每次访问到i时都进行dp
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 300005
struct Edge{int to,nxt;}edge[maxn<<1];
int head[maxn],tot,n,m,ans;
char a[maxn];
void init(){
memset(head,-1,sizeof head);
tot=0;
}
void addedge(int u,int v){
edge[tot].to=v;edge[tot].nxt=head[u];head[u]=tot++;
}
int in[maxn],dp[maxn][26];
int main(){
init();
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
addedge(u,v);
in[v]++;
}
queue<int>q;ans=1;
int cnt=0;
for(int i=1;i<=n;i++)
if(in[i]==0){
q.push(i);
dp[i][a[i]-'a']++;
}
while(!q.empty()){
int u=q.front();q.pop();
cnt++;
for(int i=head[u];i!=-1;i=edge[i].nxt){
int v=edge[i].to;
in[v]--;
for(int j=0;j<26;j++)
dp[v][j]=max(dp[v][j],dp[u][j]);
if(in[v]==0){
q.push(v);
dp[v][a[v]-'a']++;
}
}
}
if(cnt<n)puts("-1");
else {
for(int i=1;i<=n;i++)
for(int j=0;j<26;j++)
ans=max(ans,dp[i][j]);
cout<<ans<<endl;
}
return 0;
}