#include <bits/stdc++.h>
using namespace std;
const long long INF = 2e9 + 100;
const long long MOD = 1e9 + 7;
const long long N = 1e6 + 10;
const long long nul = 0;
const long long SIZE = 1e6 * 3;
const long double pi = atan2(0, -1);
string s;
vector<vector<long long> > gr;
vector<long long> used, tp;
bool flag = 0;
void dfs1(long long v) {
  used[v] = 1;
  for (long long u : gr[v]) {
    if (used[u] == 0) {
      dfs1(u);
    } else if (used[u] == 1) {
      flag = 1;
    }
  }
  used[v] = 2;
  tp.push_back(v);
}
vector<vector<long long> > dp;
void dfs2(long long v) {
  used[v] = 1;
  for (long long u : gr[v]) {
    if (used[u] == 0) {
      dfs2(u);
    }
  }
  for (long long i = 0; i < 26; i++) {
    for (long long u : gr[v]) {
      dp[v][i] = max(dp[v][i], dp[u][i]);
    }
  }
  dp[v][s[v] - 'a']++;
}
signed main() {
  cin.tie(0);
  cout.tie(0);
  ios_base::sync_with_stdio(0);
  long long n, m;
  cin >> n >> m;
  cin >> s;
  gr.resize(n);
  used.resize(n, 0);
  for (long long i = 0; i < m; i++) {
    long long v, u;
    cin >> v >> u;
    v--;
    u--;
    gr[v].push_back(u);
  }
  for (long long i = 0; i < n; i++) {
    if (used[i] == 0) {
      dfs1(i);
    }
  }
  if (flag) {
    cout << -1 << endl;
    return 0;
  }
  for (long long &i : used) i = 0;
  reverse((tp).begin(), (tp).end());
  dp.resize(n, vector<long long>(26, 0));
  long long ans = 0;
  for (long long v : tp) {
    if (used[v] == 0) {
      dfs2(v);
      for (long long i = 0; i < 26; i++) {
        ans = max(ans, dp[v][i]);
      }
    }
  }
  cout << ans << endl;
}
