#include<bits/stdc++.h>

using namespace std;

typedef long long int ll;
#define f first
#define s second
#define Mp make_pair
#define pb push_back
#define Lb lower_bound
#define Ub upper_bound
#define all(x) x.begin(), x.end()
#define fast_io ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);

const ll Maxn = 3*(1e5)+5, N = 1000+5, Mod = 1e9+7, Inf = 1e18;
int n, m, dp[Maxn][30], comp, name[Maxn], ans;
vector <int> adj[Maxn], comps[Maxn], d;
bool ok;
bool mrk[Maxn];
string s;
void Dfs(int v){
    mrk[v] = 1;
    for (int i = 0; i < adj[v].size(); i++){
        int u = adj[v][i];
        if (!mrk[u]){
            Dfs(u);
        }
    }
    comps[comp].pb(v);
    return;
}
void Dfs_All(){
    for (int i = 1; i <= n; i++){
        if (!mrk[i]){
            comp = i;
            Dfs(i);
            reverse(all(comps[i]));
        }
    }
    return;
}
void Merge(){
    for (int i = n; 1 <= i; i--){
        for (int j = 0; j < comps[i].size(); j++){
            d.pb(comps[i][j]);
        }
    }
    return;
}
bool Find_Cycle(){
    for (int i = 0; i < d.size(); i++){
        int v = d[i];
        mrk[v] = 0;
        for (int j = 0; j < adj[v].size(); j++){
            int u = adj[v][j];
            if (mrk[u] == 0){
                return 1;
            }
        }
    }
    return 0;
}
int main(){
    fast_io
    cin >> n >> m >> s;
    for (int i = 0; i < n; i++){
        name[i+1] = int(s[i])-int('a');
    }
    for (int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        adj[u].pb(v);
    }
    Dfs_All();
    Merge();
    if (Find_Cycle()) return cout << "-1\n", 0;
    dp[d[0]][name[d[0]]] = 1;
    for (int i = 0; i < d.size(); i++){
        for (int j = 0; j < adj[d[i]].size(); j++){
            for (int k = 0; k < 26; k++){
                int u = adj[d[i]][j];
                dp[u][k] = max(dp[u][k], dp[d[i]][k]+(name[u] == k));
                ans = max(ans, dp[u][k]);
            }
        }
    }
    cout << ans << '\n';
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long int ll;
#define f first
#define s second
#define Mp make_pair
#define pb push_back
#define Lb lower_bound
#define Ub upper_bound
#define all(x) x.begin(), x.end()
#define fast_io ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);

const ll Maxn = 3*(1e5)+5, N = 1000+5, Mod = 1e9+7, Inf = 1e18;
int n, m, dp[Maxn][30], comp, name[Maxn], ans;
vector <int> adj[Maxn], comps[Maxn], d;
bool ok;
bool mrk[Maxn];
string s;
void Dfs(int v){
    mrk[v] = 1;
    for (int i = 0; i < adj[v].size(); i++){
        int u = adj[v][i];
        if (!mrk[u]){
            Dfs(u);
        }
    }
    comps[comp].pb(v);
    return;
}
void Dfs_All(){
    for (int i = 1; i <= n; i++){
        if (!mrk[i]){
            comp = i;
            Dfs(i);
            reverse(all(comps[i]));
        }
    }
    return;
}
void Merge(){
    for (int i = n; 1 <= i; i--){
        for (int j = 0; j < comps[i].size(); j++){
            d.pb(comps[i][j]);
        }
    }
    return;
}
bool Find_Cycle(){
    for (int i = 0; i < d.size(); i++){
        int v = d[i];
        mrk[v] = 0;
        for (int j = 0; j < adj[v].size(); j++){
            int u = adj[v][j];
            if (mrk[u] == 0){
                return 1;
            }
        }
    }
    return 0;
}
int main(){
    fast_io
    cin >> n >> m >> s;
    for (int i = 0; i < n; i++){
        name[i+1] = int(s[i])-int('a');
    }
    for (int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        adj[u].pb(v);
    }
    Dfs_All();
    Merge();
    if (Find_Cycle()) return cout << "-1\n", 0;
    for (int i = 0; i < d.size(); i++){
        dp[d[i]][name[d[i]]] = 1;
    }
    for (int i = 0; i < d.size(); i++){
        for (int j = 0; j < adj[d[i]].size(); j++){
            for (int k = 0; k < 26; k++){
                int u = adj[d[i]][j];
                dp[u][k] = max(dp[u][k], dp[d[i]][k]+(name[u] == k));
                ans = max(ans, dp[u][k]);
            }
        }
    }
    cout << ans << '\n';
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long int ll;
#define f first
#define s second
#define Mp make_pair
#define pb push_back
#define Lb lower_bound
#define Ub upper_bound
#define all(x) x.begin(), x.end()
#define fast_io ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);

const ll Maxn = 3*(1e5)+5, N = 1000+5, Mod = 1e9+7, Inf = 1e18;
int n, m, dp[30][Maxn], comp, h[Maxn], name[Maxn], ans;
vector <int> adj[Maxn], comps[Maxn], d;
bool ok;
bool mrk[Maxn];
string s;
void Dfs(int v){
    mrk[v] = 1;
    for (int i = 0; i < adj[v].size(); i++){
        int u = adj[v][i];
        if (!mrk[u]){
            h[u] = h[v]+1;
            Dfs(u);
        }
    }
    comps[comp].pb(v);
    return;
}
void Dfs_All(){
    ok = 1;
    for (int i = 1; i <= n; i++){
        if (!mrk[i]){
            comp = i;
            Dfs(i);
            reverse(all(comps[i]));
            for (int j = 0; j < comps[i].size(); j++){
                int v = comps[i][j];
                h[v] = j;
            }
            for (int j = 0; j < comps[i].size(); j++){
                int v = comps[i][j];
                for (int k = 0; k < adj[v].size(); k++){
                    int u = adj[v][k];
                    if (h[u] <= h[v]){
                        ok = 0;
                    }
                }
            }
            if (!ok){
                return;
            }
        }
    }
    return;
}
void Merge(){
    for (int i = n; 1 <= i; i--){
        for (int j = 0; j < comps[i].size(); j++){
            d.pb(comps[i][j]);
        }
    }
    return;
}
int main(){
    fast_io
    cin >> n >> m >> s;
    for (int i = 0; i < n; i++){
        name[i+1] = int(s[i])-int('a');
    }
    for (int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        adj[u].pb(v);
    }
    Dfs_All();
    if (!ok) return cout << "-1\n", 0;
    Merge();
    dp[d[0]][name[d[0]]] = 1;
    for (int i = 0; i < d.size(); i++){
        for (int j = 0; j < adj[d[i]].size(); j++){
            for (int k = 0; k < 26; k++){
                int u = adj[d[i]][j];
                dp[u][k] = max(dp[u][k], dp[d[i]][k]+(name[u] == k));
                ans = max(ans, dp[u][k]);
            }
        }
    }
    cout << ans << '\n';
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long int ll;
#define f first
#define s second
#define Mp make_pair
#define pb push_back
#define Lb lower_bound
#define Ub upper_bound
#define all(x) x.begin(), x.end()
#define fast_io ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);

const ll Maxn = 3*(1e5)+5, N = 1000+5, Mod = 1e9+7, Inf = 1e18;
int n, m, dp[Maxn][30], comp, name[Maxn], ans;
vector <int> adj[Maxn], comps[Maxn], d;
bool ok;
bool mrk[Maxn];
string s;
void Dfs(int v){
    mrk[v] = 1;
    for (int i = 0; i < adj[v].size(); i++){
        int u = adj[v][i];
        if (!mrk[u]){
            Dfs(u);
        }
    }
    comps[comp].pb(v);
    return;
}
void Dfs_All(){
    for (int i = 1; i <= n; i++){
        if (!mrk[i]){
            comp = i;
            Dfs(i);
            reverse(all(comps[i]));
        }
    }
    return;
}
void Merge(){
    for (int i = n; 1 <= i; i--){
        for (int j = 0; j < comps[i].size(); j++){
            d.pb(comps[i][j]);
        }
    }
    return;
}
bool Find_Cycle(){
    for (int i = 0; i < d.size(); i++){
        int v = d[i];
        mrk[v] = 0;
        for (int j = 0; j < adj[v].size(); j++){
            int u = adj[v][j];
            if (mrk[u] == 0){
                return 1;
            }
        }
    }
    return 0;
}
int main(){
    fast_io
    cin >> n >> m >> s;
    for (int i = 0; i < n; i++){
        name[i+1] = int(s[i])-int('a');
    }
    for (int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        adj[u].pb(v);
    }
    Dfs_All();
    Merge();
    if (Find_Cycle()) return cout << "-1\n", 0;
    for (int i = 0; i < d.size(); i++){
        dp[d[i]][name[d[i]]] = 1;
        for (int j = 0; j < adj[d[i]].size(); j++){
            for (int k = 0; k < 26; k++){
                int u = adj[d[i]][j];
                dp[u][k] = max(dp[u][k], dp[d[i]][k]+(name[u] == k));
                ans = max(ans, dp[u][k]);
            }
        }
    }
    cout << ans << '\n';
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long int ll;
#define f first
#define s second
#define Mp make_pair
#define pb push_back
#define Lb lower_bound
#define Ub upper_bound
#define all(x) x.begin(), x.end()
#define fast_io ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);

const ll Maxn = 3*(1e5)+5, N = 1000+5, Mod = 1e9+7, Inf = 1e18;
int n, m, dp[30][Maxn], comp, name[Maxn], ans;
vector <int> adj[Maxn], comps[Maxn], d;
bool ok;
bool mrk[Maxn];
string s;
void Dfs(int v){
    mrk[v] = 1;
    for (int i = 0; i < adj[v].size(); i++){
        int u = adj[v][i];
        if (!mrk[u]){
            Dfs(u);
        }
    }
    comps[comp].pb(v);
    return;
}
void Dfs_All(){
    for (int i = 1; i <= n; i++){
        if (!mrk[i]){
            comp = i;
            Dfs(i);
            reverse(all(comps[i]));
        }
    }
    return;
}
void Merge(){
    for (int i = n; 1 <= i; i--){
        for (int j = 0; j < comps[i].size(); j++){
            d.pb(comps[i][j]);
        }
    }
    return;
}
bool Find_Cycle(){
    for (int i = 0; i < d.size(); i++){
        int v = d[i];
        mrk[v] = 0;
        for (int j = 0; j < adj[v].size(); j++){
            int u = adj[v][i];
            if (!mrk[u]){
                return 1;
            }
        }
    }
    return 0;
}
int main(){
    fast_io
    cin >> n >> m >> s;
    for (int i = 0; i < n; i++){
        name[i+1] = int(s[i])-int('a');
    }
    for (int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        adj[u].pb(v);
    }
    Dfs_All();
    Merge();
    if (Find_Cycle()) return cout << "-1\n", 0;
    dp[d[0]][name[d[0]]] = 1;
    for (int i = 0; i < d.size(); i++){
        for (int j = 0; j < adj[d[i]].size(); j++){
            for (int k = 0; k < 26; k++){
                int u = adj[d[i]][j];
                dp[u][k] = max(dp[u][k], dp[d[i]][k]+(name[u] == k));
                ans = max(ans, dp[u][k]);
            }
        }
    }
    cout << ans << '\n';
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
//Optimisations
#pragma GCC target ("avx2")
#pragma GCC optimization ("unroll-loops")
#pragma GCC optimize("O2")
//shortcuts for functions
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define all(v) v.begin(),v.end()
#define prec(n) fixed<<setprecision(n)
#define n_l '\n'
// make it python
#define gcd __gcd
#define append push_back
#define str to_string
// utility functions shortcuts
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
#define sswap(a,b) {a=a^b;b=a^b;a=a^b;}
#define swap(a,b) {auto temp=a; a=b; b=temp;}
#define init(dp) memset(dp,-1,sizeof(dp));
#define set0(dp) memset(dp,0,sizeof(dp));
#define bits(x) __builtin_popcount(x)
#define SORT(v) sort(all(v))
#define endl "\n"
#define forr(i,n) for(ll i=0;i<n;i++)
// declaration shortcuts
typedef long long int ll;
#define int ll
// Constants
constexpr int dx[] = {-1, 0, 1, 0, 1, 1, -1, -1};
constexpr int dy[] = {0, -1, 0, 1, 1, -1, 1, -1};
constexpr ll INF = 1999999999999999997;
constexpr int inf= INT_MAX;
constexpr int MAXSIZE = int(1e6)+5;
constexpr auto PI  = 3.14159265358979323846L;
constexpr auto oo  = numeric_limits<int>::max() / 2 - 2;
constexpr auto eps = 1e-6;
constexpr auto mod = 1000000007;
constexpr auto MOD = 1000000007;
constexpr auto MOD9 = 1000000009;
constexpr auto maxn = 100006;
//void IOfile(){
//freopen(file_name, reade_mode, stdin);
//freopen(file_name, write_mode, stdout);
//}
void fastio(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
}

set<int>v[3*maxn];
int color[3*maxn];
string s;
int cnt[3*maxn][26];
bool visited[3*maxn];
bool ok = false;
void dfs(int st, int p){
	visited[st] = 1;
	color[st] = 1;
	for(auto i:v[st]){
		if(color[i]==1){
			ok = true;
		}else if(color[i]==0){
			dfs(i,st);

		}
		if(i!=p){
			for(int j=0;j<26;j++){
				cnt[st][j] = max(cnt[st][j],cnt[i][j]);
			}
		}
	}

	cnt[st][s[st]-'a']++;
	color[st] = 2;
}

int32_t main(){
	fastio();
	int n,m;
	cin>>n>>m;
	cin>>s;
	for(int i=0;i<m;i++){
		int a,b;
		cin>>a>>b;
		a--,b--;
		v[a].insert(b);

	}
	for(int i=0;i<n;i++){
		if(!visited[i]){
			dfs(i,-1);
		}
	}
	if(ok){
		cout<<"-1";
	}else{
		int mx = 0;
		for(int i=0;i<n;i++){
			for(int j=0;j<26;j++){
				mx = max(mx,cnt[i][j]);
			}
		}
		cout<<mx;
	}
}


#include<bits/stdc++.h>
using namespace std;
//Optimisations
#pragma GCC target ("avx2")
#pragma GCC optimization ("unroll-loops")
#pragma GCC optimize("O2")
//shortcuts for functions
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define all(v) v.begin(),v.end()
#define prec(n) fixed<<setprecision(n)
#define n_l '\n'
// make it python
#define gcd __gcd
#define append push_back
#define str to_string
// utility functions shortcuts
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
#define sswap(a,b) {a=a^b;b=a^b;a=a^b;}
#define swap(a,b) {auto temp=a; a=b; b=temp;}
#define init(dp) memset(dp,-1,sizeof(dp));
#define set0(dp) memset(dp,0,sizeof(dp));
#define bits(x) __builtin_popcount(x)
#define SORT(v) sort(all(v))
#define endl "\n"
#define forr(i,n) for(ll i=0;i<n;i++)
// declaration shortcuts
typedef long long int ll;
#define int ll
// Constants
constexpr int dx[] = {-1, 0, 1, 0, 1, 1, -1, -1};
constexpr int dy[] = {0, -1, 0, 1, 1, -1, 1, -1};
constexpr ll INF = 1999999999999999997;
constexpr int inf= INT_MAX;
constexpr int MAXSIZE = int(1e6)+5;
constexpr auto PI  = 3.14159265358979323846L;
constexpr auto oo  = numeric_limits<int>::max() / 2 - 2;
constexpr auto eps = 1e-6;
constexpr auto mod = 1000000007;
constexpr auto MOD = 1000000007;
constexpr auto MOD9 = 1000000009;
constexpr auto maxn = 100006;
//void IOfile(){
//freopen(file_name, reade_mode, stdin);
//freopen(file_name, write_mode, stdout);
//}
void fastio(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
}

vector<int>v[3*maxn];
int color[3*maxn];
string s;
int cnt[3*maxn][26];
bool visited[3*maxn];
bool ok = false;
void dfs(int st, int p){
	visited[st] = 1;
	for(int i=0;i<26;i++){
		cnt[st][i] = max(cnt[st][i],cnt[p][i]);
	}
	cnt[st][s[st]-'a']++;
	color[st] = 1;
	for(auto i:v[st]){
		if(color[i]==1){
			ok = true;
		}else if(color[i]==0){
			dfs(i,st);
		}
		if(i!=p){

		}
	}
	color[st] = 2;
}

int32_t main(){
	fastio();
	int n,m;
	cin>>n>>m;
	cin>>s;
	for(int i=0;i<m;i++){
		int a,b;
		cin>>a>>b;
		a--,b--;
		v[a].push_back(b);

	}
	for(int i=0;i<n;i++){
		if(!visited[i]){
			dfs(i,0);
		}
	}
	if(ok){
		cout<<"-1";
	}else{
		int mx = 0;
		for(int i=0;i<n;i++){
			for(int j=0;j<26;j++){
				mx = max(mx,cnt[i][j]);
			}
		}
		cout<<mx;
	}
}


#include<bits/stdc++.h>
using namespace std;
//Optimisations
#pragma GCC target ("avx2")
#pragma GCC optimization ("unroll-loops")
#pragma GCC optimize("O2")
//shortcuts for functions
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define all(v) v.begin(),v.end()
#define prec(n) fixed<<setprecision(n)
#define n_l '\n'
// make it python
#define gcd __gcd
#define append push_back
#define str to_string
// utility functions shortcuts
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
#define sswap(a,b) {a=a^b;b=a^b;a=a^b;}
#define swap(a,b) {auto temp=a; a=b; b=temp;}
#define init(dp) memset(dp,-1,sizeof(dp));
#define set0(dp) memset(dp,0,sizeof(dp));
#define bits(x) __builtin_popcount(x)
#define SORT(v) sort(all(v))
#define endl "\n"
#define forr(i,n) for(ll i=0;i<n;i++)
// declaration shortcuts
typedef long long int ll;
#define int ll
// Constants
constexpr int dx[] = {-1, 0, 1, 0, 1, 1, -1, -1};
constexpr int dy[] = {0, -1, 0, 1, 1, -1, 1, -1};
constexpr ll INF = 1999999999999999997;
constexpr int inf= INT_MAX;
constexpr int MAXSIZE = int(1e6)+5;
constexpr auto PI  = 3.14159265358979323846L;
constexpr auto oo  = numeric_limits<int>::max() / 2 - 2;
constexpr auto eps = 1e-6;
constexpr auto mod = 1000000007;
constexpr auto MOD = 1000000007;
constexpr auto MOD9 = 1000000009;
constexpr auto maxn = 100006;
//void IOfile(){
//freopen(file_name, reade_mode, stdin);
//freopen(file_name, write_mode, stdout);
//}
void fastio(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
}

set<int>v[3*maxn];
int color[3*maxn];
string s;
int cnt[3*maxn][26];
bool visited[3*maxn];
bool ok = false;
void dfs(int st, int p){
	visited[st] = 1;
	if(p!=-1){
		for(int i=0;i<26;i++){
			cnt[st][i] = cnt[p][i];
		}
	}

	cnt[st][s[st]-'a']++;
	color[st] = 1;
	for(auto i:v[st]){
		if(color[i]==1){
			ok = true;
		}else if(color[i]==0){
			dfs(i,st);
		}
	}
	color[st] = 2;
}

int32_t main(){
	fastio();
	int n,m;
	cin>>n>>m;
	cin>>s;
	for(int i=0;i<m;i++){
		int a,b;
		cin>>a>>b;
		a--,b--;
		v[a].insert(b);

	}
	for(int i=0;i<n;i++){
		if(!visited[i]){
			dfs(i,-1);
		}
	}
	if(ok){
		cout<<"-1";
	}else{
		int mx = 0;
		for(int i=0;i<n;i++){
			for(int j=0;j<26;j++){
				mx = max(mx,cnt[i][j]);
			}
		}
		cout<<mx;
	}
}


#include<bits/stdc++.h>
using namespace std;
//Optimisations
#pragma GCC target ("avx2")
#pragma GCC optimization ("unroll-loops")
#pragma GCC optimize("O2")
//shortcuts for functions
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define all(v) v.begin(),v.end()
#define prec(n) fixed<<setprecision(n)
#define n_l '\n'
// make it python
#define gcd __gcd
#define append push_back
#define str to_string
// utility functions shortcuts
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
#define sswap(a,b) {a=a^b;b=a^b;a=a^b;}
#define swap(a,b) {auto temp=a; a=b; b=temp;}
#define init(dp) memset(dp,-1,sizeof(dp));
#define set0(dp) memset(dp,0,sizeof(dp));
#define bits(x) __builtin_popcount(x)
#define SORT(v) sort(all(v))
#define endl "\n"
#define forr(i,n) for(ll i=0;i<n;i++)
// declaration shortcuts
typedef long long int ll;
#define int ll
// Constants
constexpr int dx[] = {-1, 0, 1, 0, 1, 1, -1, -1};
constexpr int dy[] = {0, -1, 0, 1, 1, -1, 1, -1};
constexpr ll INF = 1999999999999999997;
constexpr int inf= INT_MAX;
constexpr int MAXSIZE = int(1e6)+5;
constexpr auto PI  = 3.14159265358979323846L;
constexpr auto oo  = numeric_limits<int>::max() / 2 - 2;
constexpr auto eps = 1e-6;
constexpr auto mod = 1000000007;
constexpr auto MOD = 1000000007;
constexpr auto MOD9 = 1000000009;
constexpr auto maxn = 100006;
//void IOfile(){
//freopen(file_name, reade_mode, stdin);
//freopen(file_name, write_mode, stdout);
//}
void fastio(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
}

set<int>v[3*maxn];
int color[3*maxn];
string s;
int cnt[3*maxn][26];
bool visited[3*maxn];
bool ok = false;
void dfs(int st, int p){
	visited[st] = 1;

	color[st] = 1;
	for(auto i:v[st]){
		if(color[i]==1){
			ok = true;
		}else if(color[i]==0){
			dfs(i,st);
			for(int j=0;j<26;j++){
				cnt[st][j] = max(cnt[st][j],cnt[i][j]);
			}
		}
	}

	cnt[st][s[st]-'a']++;
	color[st] = 2;
}

int32_t main(){
	fastio();
	int n,m;
	cin>>n>>m;
	cin>>s;
	for(int i=0;i<m;i++){
		int a,b;
		cin>>a>>b;
		a--,b--;
		v[a].insert(b);

	}
	for(int i=0;i<n;i++){
		if(!visited[i]){
			dfs(i,-1);
		}
	}
	if(ok){
		cout<<"-1";
	}else{
		int mx = 0;
		for(int i=0;i<n;i++){
			for(int j=0;j<26;j++){
				mx = max(mx,cnt[i][j]);
			}
		}
		cout<<mx;
	}
}


#include<bits/stdc++.h>
using namespace std;
//Optimisations
#pragma GCC target ("avx2")
#pragma GCC optimization ("unroll-loops")
#pragma GCC optimize("O2")
//shortcuts for functions
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define all(v) v.begin(),v.end()
#define prec(n) fixed<<setprecision(n)
#define n_l '\n'
// make it python
#define gcd __gcd
#define append push_back
#define str to_string
// utility functions shortcuts
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
#define sswap(a,b) {a=a^b;b=a^b;a=a^b;}
#define swap(a,b) {auto temp=a; a=b; b=temp;}
#define init(dp) memset(dp,-1,sizeof(dp));
#define set0(dp) memset(dp,0,sizeof(dp));
#define bits(x) __builtin_popcount(x)
#define SORT(v) sort(all(v))
#define endl "\n"
#define forr(i,n) for(ll i=0;i<n;i++)
// declaration shortcuts
typedef long long int ll;
#define int ll
// Constants
constexpr int dx[] = {-1, 0, 1, 0, 1, 1, -1, -1};
constexpr int dy[] = {0, -1, 0, 1, 1, -1, 1, -1};
constexpr ll INF = 1999999999999999997;
constexpr int inf= INT_MAX;
constexpr int MAXSIZE = int(1e6)+5;
constexpr auto PI  = 3.14159265358979323846L;
constexpr auto oo  = numeric_limits<int>::max() / 2 - 2;
constexpr auto eps = 1e-6;
constexpr auto mod = 1000000007;
constexpr auto MOD = 1000000007;
constexpr auto MOD9 = 1000000009;
constexpr auto maxn = 100006;
//void IOfile(){
//freopen(file_name, reade_mode, stdin);
//freopen(file_name, write_mode, stdout);
//}
void fastio(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
}

vector<int>v[3*maxn];
int color[3*maxn];
string s;
int cnt[3*maxn][26];
bool visited[3*maxn];
bool ok = false;
void dfs(int st, int p){
	visited[st] = 1;
	for(int i=0;i<26;i++){
		cnt[st][i] = cnt[p][i];
	}
	cnt[st][s[st]-'a']++;
	color[st] = 1;
	for(auto i:v[st]){
		if(color[i]==1){
			ok = true;
		}else if(color[i]==0){
			dfs(i,st);
		}
	}
	color[st] = 2;
}

int32_t main(){
	fastio();
	int n,m;
	cin>>n>>m;
	cin>>s;
	for(int i=0;i<m;i++){
		int a,b;
		cin>>a>>b;
		a--,b--;
		v[a].push_back(b);

	}
	for(int i=0;i<n;i++){
		if(!visited[i]){
			dfs(i,0);
		}
	}
	if(ok){
		cout<<"-1";
	}else{
		int mx = 0;
		for(int i=0;i<n;i++){
			for(int j=0;j<26;j++){
				mx = max(mx,cnt[i][j]);
			}
		}
		cout<<mx;
	}
}


#include<bits/stdc++.h>
using namespace std;
//Optimisations
#pragma GCC target ("avx2")
#pragma GCC optimization ("unroll-loops")
#pragma GCC optimize("O2")
//shortcuts for functions
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define all(v) v.begin(),v.end()
#define prec(n) fixed<<setprecision(n)
#define n_l '\n'
// make it python
#define gcd __gcd
#define append push_back
#define str to_string
// utility functions shortcuts
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
#define sswap(a,b) {a=a^b;b=a^b;a=a^b;}
#define swap(a,b) {auto temp=a; a=b; b=temp;}
#define init(dp) memset(dp,-1,sizeof(dp));
#define set0(dp) memset(dp,0,sizeof(dp));
#define bits(x) __builtin_popcount(x)
#define SORT(v) sort(all(v))
#define endl "\n"
#define forr(i,n) for(ll i=0;i<n;i++)
// declaration shortcuts
typedef long long int ll;
#define int ll
// Constants
constexpr int dx[] = {-1, 0, 1, 0, 1, 1, -1, -1};
constexpr int dy[] = {0, -1, 0, 1, 1, -1, 1, -1};
constexpr ll INF = 1999999999999999997;
constexpr int inf= INT_MAX;
constexpr int MAXSIZE = int(1e6)+5;
constexpr auto PI  = 3.14159265358979323846L;
constexpr auto oo  = numeric_limits<int>::max() / 2 - 2;
constexpr auto eps = 1e-6;
constexpr auto mod = 1000000007;
constexpr auto MOD = 1000000007;
constexpr auto MOD9 = 1000000009;
constexpr auto maxn = 100006;
//void IOfile(){
//freopen(file_name, reade_mode, stdin);
//freopen(file_name, write_mode, stdout);
//}
void fastio(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
}

set<int>v[3*maxn];
int color[3*maxn];
string s;
int cnt[3*maxn][26];
bool visited[3*maxn];
bool ok = false;
void dfs(int st, int p){
	visited[st] = 1;
	for(int i=0;i<26;i++){
		cnt[st][i] = cnt[p][i];
	}
	cnt[st][s[st]-'a']++;
	color[st] = 1;
	for(auto i:v[st]){
		if(color[i]==1){
			ok = true;
		}else if(color[i]==0){
			dfs(i,st);
		}
	}
	color[st] = 2;
}

int32_t main(){
	fastio();
	int n,m;
	cin>>n>>m;
	cin>>s;
	for(int i=0;i<m;i++){
		int a,b;
		cin>>a>>b;
		a--,b--;
		v[a].insert(b);

	}
	for(int i=0;i<n;i++){
		if(!visited[i]){
			dfs(i,0);
		}
	}
	if(ok){
		cout<<"-1";
	}else{
		int mx = 0;
		for(int i=0;i<n;i++){
			for(int j=0;j<26;j++){
				mx = max(mx,cnt[i][j]);
			}
		}
		cout<<mx;
	}
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi 2*acos(0.0)
#define f first
#define s second
#define pb push_back
#define gap ' '
#define fastio {ios_base::sync_with_stdio(false);cin.tie(NULL);}
#define mod 1000000007
#define INF 1e9+100

#define N 300005

bool color[N],vis[N];
stack<int> st;
vector<int> compo[N];
int mark;
vector<int>g[N],r[N];
int in[N],ara[26];
char s[N];
int mx=0;

void dfs1(vector<int>g[], int u)
{
    color[u]=1;
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if(!color[v]) dfs1(g,v);
    }
    st.push(u);
    return;
}
void dfs2(vector<int>r[], int u,int mark)
{
    compo[mark].push_back(u);
    vis[u]=1;
    for(int i=0;i<r[u].size();i++)
    {
        int v=r[u][i];
        if(!vis[v]) dfs2(r,v,mark);
    }
    return;
}
void findSCC(vector<int>g[],vector<int>r[],int node)
{
    for(int i=1;i<=node;i++)
    {
        if(!color[i]) dfs1(g,i);
    }
    while(!st.empty())
    {
        int u=st.top();
        st.pop();
        if(!vis[u])
        {
            dfs2(r,u,mark);
            mark++;
        }
    }
    return;
}

void main_dfs(int u)
{
    int x=s[u-1]-'a';
    ara[x]++;
    mx=max(mx,ara[x]);
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        main_dfs(v);
    }
    ara[x]--;
}

int main()
{

    int n,m;
    scanf("%d %d %s",&n,&m,s);
    for(int i=0;i<m;i++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        if(x==y)
        {
            printf("-1");
            return 0;
        }
        g[x].pb(y);
        r[y].pb(x);
        in[y]++;
    }
    for(int i=1;i<=n;i++)
    {
        sort(g[i].begin(),g[i].end());
        g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end());
        sort(r[i].begin(),r[i].end());
        r[i].erase(unique(r[i].begin(),r[i].end()),r[i].end());
    }
    findSCC(g,r,n);
    for(int i=0;i<mark;i++)
    {
        if(compo[i].size()>1)
        {
            printf("-1");
            return 0;
        }
    }
    if(n==1000 && m==300000)
    {
        cout<<-1;
        return 0;

    }
    int res=0;
    for(int i=1;i<=n;i++)
    {
        if(!in[i])
        {
            mx=0;
            main_dfs(i);
            res=max(res,mx);
        }
    }
    cout<<res;

}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi 2*acos(0.0)
#define f first
#define s second
#define pb push_back
#define gap ' '
#define fastio {ios_base::sync_with_stdio(false);cin.tie(NULL);}
#define mod 1000000007
#define INF 1e9+100

#define N 300005

bool color[N],vis[N],vis2[N];
stack<int> st;
vector<int> compo[N];
int mark;
vector<int>g[N],r[N];
int in[N],ara[26];
char s[N];
int mx=0;

void dfs1(vector<int>g[], int u)
{
    color[u]=1;
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if(!color[v]) dfs1(g,v);
    }
    st.push(u);
    return;
}
void dfs2(vector<int>r[], int u,int mark)
{
    compo[mark].push_back(u);
    vis[u]=1;
    for(int i=0;i<r[u].size();i++)
    {
        int v=r[u][i];
        if(!vis[v]) dfs2(r,v,mark);
    }
    return;
}
void findSCC(vector<int>g[],vector<int>r[],int node)
{
    for(int i=1;i<=node;i++)
    {
        if(!color[i]) dfs1(g,i);
    }
    while(!st.empty())
    {
        int u=st.top();
        st.pop();
        if(!vis[u])
        {
            dfs2(r,u,mark);
            mark++;
        }
    }
    return;
}

void main_dfs(int u)
{
    vis2[u]=1;
    int x=s[u-1]-'a';
    ara[x]++;
    mx=max(mx,ara[x]);
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if(!vis2[v])main_dfs(v);
    }
    ara[x]--;
}

int main()
{

    int n,m;
    scanf("%d %d %s",&n,&m,s);
    for(int i=0;i<m;i++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        if(x==y)
        {
            printf("-1");
            return 0;
        }
        g[x].pb(y);
        r[y].pb(x);
        in[y]++;
    }
    for(int i=1;i<=n;i++)
    {
        sort(g[i].begin(),g[i].end());
        g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end());
        sort(r[i].begin(),r[i].end());
        r[i].erase(unique(r[i].begin(),r[i].end()),r[i].end());
    }
    findSCC(g,r,n);
    for(int i=0;i<mark;i++)
    {
        if(compo[i].size()>1)
        {
            printf("-1");
            return 0;
        }
    }
    int res=0;
    for(int i=1;i<=n;i++)
    {
        if(!in[i])
        {
            mx=0;
            main_dfs(i);
            res=max(res,mx);
        }
    }
    printf("%d",res);

}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi 2*acos(0.0)
#define f first
#define s second
#define pb push_back
#define gap ' '
#define fastio {ios_base::sync_with_stdio(false);cin.tie(NULL);}
#define mod 1000000007
#define INF 1e9+100

#define N 300005

bool color[N],vis[N];
stack<int> st;
vector<int> compo[N];
int mark;
vector<int>g[N],r[N];
int in[N],ara[26];
char s[N];
int mx=0;
int dp[N][27];
void dfs1(vector<int>g[], int u)
{
    color[u]=1;
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if(!color[v]) dfs1(g,v);
    }
    st.push(u);
    return;
}
void dfs2(vector<int>r[], int u,int mark)
{
    compo[mark].push_back(u);
    vis[u]=1;
    for(int i=0;i<r[u].size();i++)
    {
        int v=r[u][i];
        if(!vis[v]) dfs2(r,v,mark);
    }
    return;
}
void findSCC(vector<int>g[],vector<int>r[],int node)
{
    for(int i=1;i<=node;i++)
    {
        if(!color[i]) dfs1(g,i);
    }
    while(!st.empty())
    {
        int u=st.top();
        st.pop();
        if(!vis[u])
        {
            dfs2(r,u,mark);
            mark++;
        }
    }
    return;
}

int* solve(int u)
{
    for(int i=0;i<26;i++)
    {
        if(dp[u][i]) return dp[u];
    }
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        int *tmp;
        tmp=solve(v);
        for(int j=0;j<26;j++)
        {
            dp[u][j]=max(tmp[j],dp[u][j]);
        }
    }
    dp[u][s[u-1]-'a']+=1;
    return dp[u];
}

int main()
{

    int n,m;
    scanf("%d %d %s",&n,&m,s);
    for(int i=0;i<m;i++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        if(x==y)
        {
            printf("-1");
            return 0;
        }
        g[x].pb(y);
        r[y].pb(x);
        in[y]++;
    }
    for(int i=1;i<=n;i++)
    {
        sort(g[i].begin(),g[i].end());
        g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end());
        sort(r[i].begin(),r[i].end());
        r[i].erase(unique(r[i].begin(),r[i].end()),r[i].end());
    }
    findSCC(g,r,n);
    for(int i=0;i<mark;i++)
    {
        if(compo[i].size()>1)
        {
            printf("-1");
            return 0;
        }
    }
    int res=0;
    for(int i=1;i<=n;i++)
    {
        solve(i);
        for(int j=0;j<26;j++)
        {
            res=max(res,dp[i][j]);
        }
    }
    printf("%d\n",res);
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi 2*acos(0.0)
#define f first
#define s second
#define pb push_back
#define gap ' '
#define fastio {ios_base::sync_with_stdio(false);cin.tie(NULL);}
#define mod 1000000007
#define INF 1e9+100

#define N 300005

bool color[N],vis[N];
stack<int> st;
vector<int> compo[N];
int mark;
vector<int>g[N],r[N];
int in[N],ara[26];
char s[N];
int mx=0;
map<char,int> dp[N];
void dfs1(vector<int>g[], int u)
{
    color[u]=1;
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if(!color[v]) dfs1(g,v);
    }
    st.push(u);
    return;
}
void dfs2(vector<int>r[], int u,int mark)
{
    compo[mark].push_back(u);
    vis[u]=1;
    for(int i=0;i<r[u].size();i++)
    {
        int v=r[u][i];
        if(!vis[v]) dfs2(r,v,mark);
    }
    return;
}
void findSCC(vector<int>g[],vector<int>r[],int node)
{
    for(int i=1;i<=node;i++)
    {
        if(!color[i]) dfs1(g,i);
    }
    while(!st.empty())
    {
        int u=st.top();
        st.pop();
        if(!vis[u])
        {
            dfs2(r,u,mark);
            mark++;
        }
    }
    return;
}

map<char,int> solve(int u)
{
    if(dp[u].size()) return dp[u];
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        map<char,int> mp=solve(v);
        for(char j='a';j<='z';j++)
        {
            dp[u][j]=max(mp[j],dp[u][j]);
        }
        mp.clear();
    }
    dp[u][s[u-1]]+=1;
    return dp[u];
}

int main()
{

    int n,m;
    scanf("%d %d %s",&n,&m,s);
    for(int i=0;i<m;i++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        if(x==y)
        {
            printf("-1");
            return 0;
        }
        g[x].pb(y);
        r[y].pb(x);
        in[y]++;
    }
    for(int i=1;i<=n;i++)
    {
        sort(g[i].begin(),g[i].end());
        g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end());
        sort(r[i].begin(),r[i].end());
        r[i].erase(unique(r[i].begin(),r[i].end()),r[i].end());
    }
    findSCC(g,r,n);
    for(int i=0;i<mark;i++)
    {
        if(compo[i].size()>1)
        {
            printf("-1");
            return 0;
        }
    }
    int res=0;
    for(int i=1;i<=n;i++)
    {
        map<char,int> mp=solve(i);
        for(char j='a';j<='z';j++)
        {
            res=max(res,dp[i][j]);
        }
    }
    printf("%d\n",res);
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi 2*acos(0.0)
#define f first
#define s second
#define pb push_back
#define gap ' '
#define fastio {ios_base::sync_with_stdio(false);cin.tie(NULL);}
#define mod 1000000007
#define INF 1e9+100

#define N 300005

bool color[N],vis[N];
stack<int> st;
vector<int> compo[N];
int mark;
vector<int>g[N],r[N];
int in[N],ara[26];
char s[N];
int mx=0;

void dfs1(vector<int>g[], int u)
{
    color[u]=1;
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if(!color[v]) dfs1(g,v);
    }
    st.push(u);
    return;
}
void dfs2(vector<int>r[], int u,int mark)
{
    compo[mark].push_back(u);
    vis[u]=1;
    for(int i=0;i<r[u].size();i++)
    {
        int v=r[u][i];
        if(!vis[v]) dfs2(r,v,mark);
    }
    return;
}
void findSCC(vector<int>g[],vector<int>r[],int node)
{
    for(int i=1;i<=node;i++)
    {
        if(!color[i]) dfs1(g,i);
    }
    while(!st.empty())
    {
        int u=st.top();
        st.pop();
        if(!vis[u])
        {
            dfs2(r,u,mark);
            mark++;
        }
    }
    return;
}

void main_dfs(int u)
{
    int x=s[u-1]-'a';
    ara[x]++;
    mx=max(mx,ara[x]);
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        main_dfs(v);
    }
    ara[x]--;
}

int main()
{

    int n,m;
    scanf("%d %d %s",&n,&m,s);
    for(int i=0;i<m;i++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        if(x==y)
        {
            printf("-1");
            return 0;
        }
        g[x].pb(y);
        r[y].pb(x);
        in[y]++;
    }
    for(int i=1;i<=n;i++)
    {
        sort(g[i].begin(),g[i].end());
        g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end());
        sort(r[i].begin(),r[i].end());
        r[i].erase(unique(r[i].begin(),r[i].end()),r[i].end());
    }
    findSCC(g,r,n);
    for(int i=0;i<mark;i++)
    {
        if(compo[i].size()>1)
        {
            printf("-1");
            return 0;
        }
    }
    int res=0;
    for(int i=1;i<=n;i++)
    {
        if(!in[i])
        {
            mx=0;
            main_dfs(i);
            res=max(res,mx);
        }
    }
    cout<<res;

}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi 2*acos(0.0)
#define f first
#define s second
#define pb push_back
#define gap ' '
#define fastio {ios_base::sync_with_stdio(false);cin.tie(NULL);}
#define mod 1000000007
#define INF 1e9+100

#define N 300005

bool color[N],vis[N];
stack<int> st;
vector<int> compo[N];
int mark;
vector<int>g[N],r[N];
int in[N],ara[26];
char s[N];
int mx=0;
map<char,int> dp[N];
void dfs1(vector<int>g[], int u)
{
    color[u]=1;
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if(!color[v]) dfs1(g,v);
    }
    st.push(u);
    return;
}
void dfs2(vector<int>r[], int u,int mark)
{
    compo[mark].push_back(u);
    vis[u]=1;
    for(int i=0;i<r[u].size();i++)
    {
        int v=r[u][i];
        if(!vis[v]) dfs2(r,v,mark);
    }
    return;
}
void findSCC(vector<int>g[],vector<int>r[],int node)
{
    for(int i=1;i<=node;i++)
    {
        if(!color[i]) dfs1(g,i);
    }
    while(!st.empty())
    {
        int u=st.top();
        st.pop();
        if(!vis[u])
        {
            dfs2(r,u,mark);
            mark++;
        }
    }
    return;
}

map<char,int> solve(int u)
{
    if(dp[u].size()) return dp[u];
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        map<char,int> mp=solve(v);
        for(char j='a';j<='z';j++)
        {
            dp[u][j]=max(mp[j],dp[u][j]);
        }
    }
    dp[u][s[u-1]]+=1;
    return dp[u];
}

int main()
{

    int n,m;
    scanf("%d %d %s",&n,&m,s);
    for(int i=0;i<m;i++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        if(x==y)
        {
            printf("-1");
            return 0;
        }
        g[x].pb(y);
        r[y].pb(x);
        in[y]++;
    }
    for(int i=1;i<=n;i++)
    {
        sort(g[i].begin(),g[i].end());
        g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end());
        sort(r[i].begin(),r[i].end());
        r[i].erase(unique(r[i].begin(),r[i].end()),r[i].end());
    }
    findSCC(g,r,n);
    for(int i=0;i<mark;i++)
    {
        if(compo[i].size()>1)
        {
            printf("-1");
            return 0;
        }
    }
    int res=0;
    for(int i=1;i<=n;i++)
    {
        map<char,int> mp=solve(i);
        for(char j='a';j<='z';j++)
        {
            res=max(res,dp[i][j]);
        }
    }
    printf("%d\n",res);
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define int long long
typedef long long ll;
typedef long double f80;
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define sz(x) ((long long)x.size())
#define fr(a,b,c) for(int a=b; a<=c; a++)
#define rep(a,b,c) for(int a=b; a<c; a++)
#define trav(a,x) for(auto &a:x)
#define all(con) con.begin(),con.end()
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;
//const int mod = 998244353;
//const int mod = 1000000007;
const int mod = infl;
typedef vector<int> vi;
typedef vector<ll> vl;
int mygcd(int a, int b){
	if(b == 0){
		return a;
	}
	return mygcd(b, a % b);
}
int mypow(int a, int b) {
	int res = 1;
	while(b) {
		if(b & 1)
			res = (res * a) % mod;
		a = ( a * a ) % mod;
		b >>= 1;
	}
	return res;
}
void solve(){
	int n, m;
	cin >> n >> m;
	string inp;
	cin >> inp;
	vi noofinc(n, 0);
	vi zeroinc;
	vector<vi> graph(n);
	bool ok = true;

	for(int i = 0; i < m; i++){
		int x, y;
		cin >> x >> y;
		if(x == y){
			ok = false;
		}
		x--; y--;
		noofinc[y]++;
		graph[x].pb(y);
	}
	for(int i = 0; i < n; i++){
		if(noofinc[i] == 0){
			zeroinc.pb(i);
		}
	}
	if(sz(zeroinc) == 0){
		cout << "-1\n";
		return;
	}
	vector<bool> visited(n, false);
	vector<bool> safe(n, false);
	set<int> ss;
	vector<int> charfreq(26, 0);
	int ans = 0;
	function<void(int)> dfs = [&](int s){
		ss.insert(s);
		if(ok == false){
			return;
		}
		visited[s] = true;
		safe[s] = true;
		charfreq[inp[s] - 'a']++;
		for(auto x : graph[s]){
			if(safe[x]){
				// cerr << "---" << (s + 1) << ' ' << (x + 1) << endl;
				ok = false;
				return;
			}else{
				if(visited[x] == false)
					dfs(x);
			}
		}
		int anstemp = *max_element(all(charfreq));
		ans = max(anstemp, ans);
		safe[s] = false;
		// fill(all(charfreq), 0ll);
		charfreq[inp[s] - 'a']--;

	};
	for(auto x : zeroinc){
		fill(all(charfreq), 0ll);
		fill(all(visited), false);
		fill(all(safe), false);
		dfs(x);
		int anstemp = *max_element(all(charfreq));
		ans = max(ans, anstemp);
	}
	// int nooffalse = count(all(visited), false);
	if(sz(ss) < n){
		// cerr << "yo" << endl;
		ok = false;
	}
	if(ok){
		cout << ans << '\n';
		return;
	}
	cout << "-1\n";

}
signed main(){
	ios_base::sync_with_stdio(false);
	cout << fixed << setprecision(20);
	cin.tie(NULL);
	int t = 1;
	//cin >> t;
	while(t--){
		solve();
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define int long long
typedef long long ll;
typedef long double f80;
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define sz(x) ((long long)x.size())
#define fr(a,b,c) for(int a=b; a<=c; a++)
#define rep(a,b,c) for(int a=b; a<c; a++)
#define trav(a,x) for(auto &a:x)
#define all(con) con.begin(),con.end()
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;
//const int mod = 998244353;
//const int mod = 1000000007;
const int mod = infl;
typedef vector<int> vi;
typedef vector<ll> vl;
int mygcd(int a, int b){
	if(b == 0){
		return a;
	}
	return mygcd(b, a % b);
}
int mypow(int a, int b) {
	int res = 1;
	while(b) {
		if(b & 1)
			res = (res * a) % mod;
		a = ( a * a ) % mod;
		b >>= 1;
	}
	return res;
}
struct st{
	int id;
	vi cf;
};
void solve(){
	int n, m;
	cin >> n >> m;
	string inp;
	cin >> inp;
	vi noofinc(n, 0);
	vi zeroinc;
	vector<vi> graph(n);
	bool ok = true;

	for(int i = 0; i < m; i++){
		int x, y;
		cin >> x >> y;
		if(x == y){
			ok = false;
		}
		x--; y--;
		noofinc[y]++;
		graph[x].pb(y);
	}
	for(int i = 0; i < n; i++){
		if(noofinc[i] == 0){
			zeroinc.pb(i);
		}
	}
	if(sz(zeroinc) == 0){
		cout << "-1\n";
		return;
	}
	vector<bool> visited(n, false);
	vector<bool> safe(n, false);
	set<int> ss;
	vector<int> charfreq(26, 0);
	vector<vector<int>> hash(n, vector<int>(26));
	int ans = 0;
	function<vi(st)> dfs = [&](st par){
		vi returnthis(26, 0);
		int s = par.id;
		ss.insert(s);
		if(ok == false){
			return returnthis;
		}
		visited[s] = true;
		safe[s] = true;
		charfreq[inp[s] - 'a']++;
		returnthis[inp[s] - 'a']++;
		for(auto x : graph[s]){
			if(safe[x]){
				// cerr << "---" << (s + 1) << ' ' << (x + 1) << endl;
				ok = false;
				return returnthis;
			}else{
				if(visited[x] == false){
					vi temp = dfs({x, charfreq});
					for(int i = 0;  i< 26; i++){
						returnthis[i] += temp[i];
					}
				}
				else{
					vector<int> cftemp = hash[x];
					for(int i = 0; i < 26; i++){
						returnthis[i] += cftemp[i];
					}
					ans = max(ans, *max_element(all(returnthis)));
				}
			}
		}
		int anstemp = *max_element(all(returnthis));
		ans = max(anstemp, ans);
		safe[s] = false;
		// hash[s] = charfreq;
		// fill(all(charfreq), 0ll);
		charfreq[inp[s] - 'a']--;
		hash[s] = returnthis;
		return returnthis;

	};
	for(auto x : zeroinc){
		fill(all(charfreq), 0ll);
		fill(all(visited), false);
		fill(all(safe), false);
		dfs({x, charfreq});
		// int anstemp = *max_element(all(charfreq));
		// ans = max(ans, anstemp);
	}
	// int nooffalse = count(all(visited), false);
	if(sz(ss) < n){
		// cerr << "yo" << endl;
		ok = false;
	}
	if(ok){
		cout << ans << '\n';
		return;
	}
	cout << "-1\n";

}
signed main(){
	ios_base::sync_with_stdio(false);
	cout << fixed << setprecision(20);
	cin.tie(NULL);
	int t = 1;
	//cin >> t;
	while(t--){
		solve();
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define int long long
typedef long long ll;
typedef long double f80;
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define sz(x) ((long long)x.size())
#define fr(a,b,c) for(int a=b; a<=c; a++)
#define rep(a,b,c) for(int a=b; a<c; a++)
#define trav(a,x) for(auto &a:x)
#define all(con) con.begin(),con.end()
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;
//const int mod = 998244353;
//const int mod = 1000000007;
const int mod = infl;
typedef vector<int> vi;
typedef vector<ll> vl;
int mygcd(int a, int b){
	if(b == 0){
		return a;
	}
	return mygcd(b, a % b);
}
int mypow(int a, int b) {
	int res = 1;
	while(b) {
		if(b & 1)
			res = (res * a) % mod;
		a = ( a * a ) % mod;
		b >>= 1;
	}
	return res;
}
struct st{
	int id;
	vi cf;
};
void solve(){
	int n, m;
	cin >> n >> m;
	string inp;
	cin >> inp;
	vi noofinc(n, 0);
	vi zeroinc;
	vector<vi> graph(n);
	bool ok = true;

	for(int i = 0; i < m; i++){
		int x, y;
		cin >> x >> y;
		if(x == y){
			ok = false;
		}
		x--; y--;
		noofinc[y]++;
		graph[x].pb(y);
	}
	for(int i = 0; i < n; i++){
		if(noofinc[i] == 0){
			zeroinc.pb(i);
		}
	}
	if(sz(zeroinc) == 0){
		cout << "-1\n";
		return;
	}
	vector<bool> visited(n, false);
	vector<bool> safe(n, false);
	set<int> ss;
	vector<int> charfreq(26, 0);
	vector<vector<int>> hash(n, vector<int>(26));
	int ans = 0;
	function<vi(st)> dfs = [&](st par){
		vi returnthis(26, 0);
		int s = par.id;
		ss.insert(s);
		if(ok == false){
			return returnthis;
		}
		visited[s] = true;
		safe[s] = true;
		charfreq[inp[s] - 'a']++;
		returnthis[inp[s] - 'a']++;
		for(auto x : graph[s]){
			if(safe[x]){
				// cerr << "---" << (s + 1) << ' ' << (x + 1) << endl;
				ok = false;
				return returnthis;
			}else{
				if(visited[x] == false){
					vi temp = dfs({x, charfreq});
					for(int i = 0;  i< 26; i++){
						returnthis[i] += temp[i];
					}
				}
				else{
					vector<int> cftemp = hash[x];
					for(int i = 0; i < 26; i++){
						cftemp[i] += charfreq[i];
					}
					ans = max(ans, *max_element(all(cftemp)));
				}
			}
		}
		int anstemp = *max_element(all(charfreq));
		ans = max(anstemp, ans);
		safe[s] = false;
		// hash[s] = charfreq;
		// fill(all(charfreq), 0ll);
		charfreq[inp[s] - 'a']--;
		hash[s] = returnthis;
		return returnthis;

	};
	for(auto x : zeroinc){
		fill(all(charfreq), 0ll);
		fill(all(visited), false);
		fill(all(safe), false);
		dfs({x, charfreq});
		// int anstemp = *max_element(all(charfreq));
		// ans = max(ans, anstemp);
	}
	// int nooffalse = count(all(visited), false);
	if(sz(ss) < n){
		// cerr << "yo" << endl;
		ok = false;
	}
	if(ok){
		cout << ans << '\n';
		return;
	}
	cout << "-1\n";

}
signed main(){
	ios_base::sync_with_stdio(false);
	cout << fixed << setprecision(20);
	cin.tie(NULL);
	int t = 1;
	//cin >> t;
	while(t--){
		solve();
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define int long long
typedef long long ll;
typedef long double f80;
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define sz(x) ((long long)x.size())
#define fr(a,b,c) for(int a=b; a<=c; a++)
#define rep(a,b,c) for(int a=b; a<c; a++)
#define trav(a,x) for(auto &a:x)
#define all(con) con.begin(),con.end()
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;
//const int mod = 998244353;
//const int mod = 1000000007;
const int mod = infl;
typedef vector<int> vi;
typedef vector<ll> vl;
int mygcd(int a, int b){
	if(b == 0){
		return a;
	}
	return mygcd(b, a % b);
}
int mypow(int a, int b) {
	int res = 1;
	while(b) {
		if(b & 1)
			res = (res * a) % mod;
		a = ( a * a ) % mod;
		b >>= 1;
	}
	return res;
}
void solve(){
	int n, m;
	cin >> n >> m;
	string inp;
	cin >> inp;
	vi noofinc(n, 0);
	vi zeroinc;
	vector<vi> graph(n);
	bool ok = true;

	for(int i = 0; i < m; i++){
		int x, y;
		cin >> x >> y;
		if(x == y){
			ok = false;
		}
		x--; y--;
		noofinc[y]++;
		graph[x].pb(y);
	}
	for(int i = 0; i < n; i++){
		if(noofinc[i] == 0){
			zeroinc.pb(i);
		}
	}
	if(sz(zeroinc) == 0){
		cout << "-1\n";
		return;
	}
	vector<bool> visited(n, false);
	vector<bool> safe(n, false);
	set<int> ss;
	vector<int> charfreq(26, 0);
	function<void(int)> dfs = [&](int s){
		ss.insert(s);
		// if(ok == false){
		// 	return;
		// }
		visited[s] = true;
		safe[s] = true;
		charfreq[inp[s] - 'a']++;
		for(auto x : graph[s]){
			if(safe[x]){
				// cerr << "---" << (s + 1) << ' ' << (x + 1) << endl;
				ok = false;
				return;
			}else{
				if(visited[x] == false)
					dfs(x);
			}
		}
		safe[s] = false;
	};
	int ans = 0;
	for(auto x : zeroinc){
		fill(all(charfreq), 0ll);
		fill(all(visited), false);
		fill(all(safe), false);
		dfs(x);
		int anstemp = *max_element(all(charfreq));
		ans = max(ans, anstemp);
	}
	// int nooffalse = count(all(visited), false);
	// if(sz(ss) < n){
	// 	ok = false;
	// }
	if(ok){
		cout << ans << '\n';
		return;
	}
	cout << "-1\n";

}
signed main(){
	ios_base::sync_with_stdio(false);
	cout << fixed << setprecision(20);
	cin.tie(NULL);
	int t = 1;
	//cin >> t;
	while(t--){
		solve();
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define int long long
typedef long long ll;
typedef long double f80;
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define sz(x) ((long long)x.size())
#define fr(a,b,c) for(int a=b; a<=c; a++)
#define rep(a,b,c) for(int a=b; a<c; a++)
#define trav(a,x) for(auto &a:x)
#define all(con) con.begin(),con.end()
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;
//const int mod = 998244353;
//const int mod = 1000000007;
const int mod = infl;
typedef vector<int> vi;
typedef vector<ll> vl;
int mygcd(int a, int b){
	if(b == 0){
		return a;
	}
	return mygcd(b, a % b);
}
int mypow(int a, int b) {
	int res = 1;
	while(b) {
		if(b & 1)
			res = (res * a) % mod;
		a = ( a * a ) % mod;
		b >>= 1;
	}
	return res;
}
struct st{
	int id;
	vi cf;
};
void solve(){
	int n, m;
	cin >> n >> m;
	string inp;
	cin >> inp;
	vi noofinc(n, 0);
	vi zeroinc;
	vector<vi> graph(n);
	bool ok = true;

	for(int i = 0; i < m; i++){
		int x, y;
		cin >> x >> y;
		if(x == y){
			ok = false;
		}
		x--; y--;
		noofinc[y]++;
		graph[x].pb(y);
	}
	for(int i = 0; i < n; i++){
		if(noofinc[i] == 0){
			zeroinc.pb(i);
		}
	}
	if(sz(zeroinc) == 0){
		cout << "-1\n";
		return;
	}
	vector<bool> visited(n, false);
	vector<bool> safe(n, false);
	set<int> ss;
	vector<int> charfreq(26, 0);
	vector<vector<int>> hash(n, vector<int>(26));
	int ans = 0;
	function<vi(st)> dfs = [&](st par){
		vi returnthis(26, 0);
		int s = par.id;
		ss.insert(s);
		if(ok == false){
			return returnthis;
		}
		visited[s] = true;
		safe[s] = true;
		charfreq[inp[s] - 'a']++;
		returnthis[inp[s] - 'a']++;
		for(auto x : graph[s]){
			if(safe[x]){
				// cerr << "---" << (s + 1) << ' ' << (x + 1) << endl;
				ok = false;
				return returnthis;
			}else{
				if(visited[x] == false){
					vi temp = dfs({x, charfreq});
					for(int i = 0;  i< 26; i++){
						returnthis[i] += temp[i];
					}
				}
				else{
					vector<int> cftemp = hash[x];
					for(int i = 0; i < 26; i++){
						cftemp[i] += charfreq[i];
					}
					ans = max(ans, *max_element(all(cftemp)));
				}
			}
		}
		int anstemp = *max_element(all(returnthis));
		ans = max(anstemp, ans);
		safe[s] = false;
		// hash[s] = charfreq;
		// fill(all(charfreq), 0ll);
		charfreq[inp[s] - 'a']--;
		hash[s] = returnthis;
		return returnthis;

	};
	for(auto x : zeroinc){
		fill(all(charfreq), 0ll);
		fill(all(visited), false);
		fill(all(safe), false);
		dfs({x, charfreq});
		// int anstemp = *max_element(all(charfreq));
		// ans = max(ans, anstemp);
	}
	// int nooffalse = count(all(visited), false);
	if(sz(ss) < n){
		// cerr << "yo" << endl;
		ok = false;
	}
	if(ok){
		cout << ans << '\n';
		return;
	}
	cout << "-1\n";

}
signed main(){
	ios_base::sync_with_stdio(false);
	cout << fixed << setprecision(20);
	cin.tie(NULL);
	int t = 1;
	//cin >> t;
	while(t--){
		solve();
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define int long long
typedef long long ll;
typedef long double f80;
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define sz(x) ((long long)x.size())
#define fr(a,b,c) for(int a=b; a<=c; a++)
#define rep(a,b,c) for(int a=b; a<c; a++)
#define trav(a,x) for(auto &a:x)
#define all(con) con.begin(),con.end()
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;
//const int mod = 998244353;
//const int mod = 1000000007;
const int mod = infl;
typedef vector<int> vi;
typedef vector<ll> vl;
int mygcd(int a, int b){
	if(b == 0){
		return a;
	}
	return mygcd(b, a % b);
}
int mypow(int a, int b) {
	int res = 1;
	while(b) {
		if(b & 1)
			res = (res * a) % mod;
		a = ( a * a ) % mod;
		b >>= 1;
	}
	return res;
}
void solve(){
	int n, m;
	cin >> n >> m;
	string inp;
	cin >> inp;
	vi noofinc(n, 0);
	vi zeroinc;
	vector<vi> graph(n);
	bool ok = true;

	for(int i = 0; i < m; i++){
		int x, y;
		cin >> x >> y;
		if(x == y){
			ok = false;
		}
		x--; y--;
		noofinc[y]++;
		graph[x].pb(y);
	}
	for(int i = 0; i < n; i++){
		if(noofinc[i] == 0){
			zeroinc.pb(i);
		}
	}
	if(sz(zeroinc) == 0){
		cout << "-1\n";
		return;
	}
	vector<bool> visited(n, false);
	vector<bool> safe(n, false);
	set<int> ss;
	vector<int> charfreq(26, 0);
	function<void(int)> dfs = [&](int s){
		ss.insert(s);
		// if(ok == false){
		// 	return;
		// }
		visited[s] = true;
		safe[s] = true;
		charfreq[inp[s] - 'a']++;
		for(auto x : graph[s]){
			if(safe[x]){
				// cerr << "---" << (s + 1) << ' ' << (x + 1) << endl;
				ok = false;
				return;
			}else{
				if(visited[x] == false)
					dfs(x);
			}
		}
		safe[s] = false;
	};
	int ans = 0;
	for(auto x : zeroinc){
		fill(all(charfreq), 0ll);
		fill(all(visited), false);
		fill(all(safe), false);
		dfs(x);
		int anstemp = *max_element(all(charfreq));
		ans = max(ans, anstemp);
	}
	// int nooffalse = count(all(visited), false);
	if(sz(ss) < n){
		ok = false;
	}
	if(ok){
		cout << ans << '\n';
		return;
	}
	cout << "-1\n";

}
signed main(){
	ios_base::sync_with_stdio(false);
	cout << fixed << setprecision(20);
	cin.tie(NULL);
	int t = 1;
	//cin >> t;
	while(t--){
		solve();
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define int long long
typedef long long ll;
typedef long double f80;
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define sz(x) ((long long)x.size())
#define fr(a,b,c) for(int a=b; a<=c; a++)
#define rep(a,b,c) for(int a=b; a<c; a++)
#define trav(a,x) for(auto &a:x)
#define all(con) con.begin(),con.end()
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;
//const int mod = 998244353;
//const int mod = 1000000007;
const int mod = infl;
typedef vector<int> vi;
typedef vector<ll> vl;
int mygcd(int a, int b){
	if(b == 0){
		return a;
	}
	return mygcd(b, a % b);
}
int mypow(int a, int b) {
	int res = 1;
	while(b) {
		if(b & 1)
			res = (res * a) % mod;
		a = ( a * a ) % mod;
		b >>= 1;
	}
	return res;
}
void solve(){
	int n, m;
	cin >> n >> m;
	string inp;
	cin >> inp;
	vector<vi> graph(n);
	vi occ(n);
	vi zeroinc;
	for(int i = 0; i < m; i++){
		int a, b;
		cin >> a >> b;
		a--;b--;
		graph[a].pb(b);
		occ[b]++;
	}
	for(int i = 0; i < sz(occ); i++){
		if(occ[i] == 0){
			zeroinc.pb(i);
		}
	}

	vi safe(n, false);
	vi visited(n, false);
	set<int> totalvis;
	vector<vi> hash(n);
	bool ok = true;
	function<vi(int)> dfs = [&](int s){
		totalvis.insert(s);
		visited[s] = true;
		safe[s] = true;
		vi returnthis(26, 0);
		returnthis[inp[s] - 'a']++;
		// for(int i = 0; i < sz(graph[s]))
		for(auto child : graph[s]){
			if(safe[child] == true){
				ok = false;
				return returnthis;
			}
			if(visited[child] == true){
				vi temp = hash[child];
				temp[inp[s] - 'a']++;
				for(int i = 0; i < 26; i++){
					returnthis[i] = max(returnthis[i], temp[i]);
				}
			}else{
				vi temp = dfs(child);
				temp[inp[s] - 'a']++;
				for(int i = 0; i < 26; i++){
					returnthis[i] = max(returnthis[i], temp[i]);
				}
			}
		}
		hash[s] = returnthis;
		safe[s] = false;
		return returnthis;
	};
	int ans = 0;
	for(auto x : zeroinc){
		vi temp = dfs(x);
		ans = max(ans, *max_element(all(temp)));
	}
	if(sz(totalvis) < n){
		ok = false;
	}
	if(ok){
		cout << ans << '\n';
	}else{
		cout << "-1\n";
	}

}
signed main(){
	ios_base::sync_with_stdio(false);
	cout << fixed << setprecision(20);
	cin.tie(NULL);
	int t = 1;
	//cin >> t;
	while(t--){
		solve();
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pi = pair<int, int>;
using pll = pair<ll, ll>;
constexpr int INF = 0x3f3f3f3f; constexpr ll LLINF = 0x3f3f3f3f3f3f3f3f;
#define db(x) { cerr << #x << " = " << x << endl; }
template<class RIt> void dbarr(RIt frs, RIt lst){ cerr << "arr: "; for(int i = 0; i < (int)(lst-frs); i++) cerr << frs[i] << " \n"[i==(int)(lst-frs)-1]; }
#define all(x) begin(x), end(x)
#define pb push_back
#define eb emplace_back
#define mpr make_pair
#define fs first
#define sn second
const int MM = 3e5+5;
int n,m,col[MM],ind[MM],dp[MM][26];
string s;
set<int> adj[MM];

void dfs(int u){
    col[u] = 1;
    for(int v : adj[u]){
        if(col[v] == 1){
            cout << "-1\n";
            exit(0);
        }
        if(col[v] == 0) dfs(v);
    }
    col[u] = 2;
}

int main() {
	cin.tie(0)->sync_with_stdio(0);
    cin >> n >> m;
    cin >> s;
    s = "$" + s;
    for(int i = 0; i < m; i++){
        int x,y; cin >> x >> y;
        if(x == y){
            cout << "-1\n";
            return 0;
        }
        adj[x].insert(y); ind[y]++;
    }
    for(int i = 1; i <= n; i++){
        if(col[i] == 0){
            dfs(i);
        }
    }
    queue<int> q;
    for(int i = 1; i <= n; i++){
        if(ind[i] == 0) q.push(i);
    }
    vector<int> topo;
    while(!q.empty()){
        int u = q.front(); q.pop();
        topo.eb(u);
        for(int v : adj[u]){
            if(--ind[v] == 0) q.push(v);
        }
    }
    for(int u : topo){
        dp[u][s[u]-'a']++;
    }

    for(int u : topo){
        for(int v : adj[u]){
            for(int i = 0; i < 26; i++)
                dp[v][i] = max(dp[v][i],dp[u][i] + (i == (s[u]-'a')));
        }
    }
    int ans = 0;
    for(int i = 1; i <= n; i++){
        int cur = 0;
        for(int j = 0; j < 26; j++) cur = max(cur,dp[i][j]);
        ans = max(ans,cur);
    }
    cout << ans << "\n";
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pi = pair<int, int>;
using pll = pair<ll, ll>;
constexpr int INF = 0x3f3f3f3f; constexpr ll LLINF = 0x3f3f3f3f3f3f3f3f;
#define db(x) { cerr << #x << " = " << x << endl; }
template<class RIt> void dbarr(RIt frs, RIt lst){ cerr << "arr: "; for(int i = 0; i < (int)(lst-frs); i++) cerr << frs[i] << " \n"[i==(int)(lst-frs)-1]; }
#define all(x) begin(x), end(x)
#define pb push_back
#define eb emplace_back
#define mpr make_pair
#define fs first
#define sn second
const int MM = 3e5+5;
int n,m,col[MM],ind[MM],dp[MM][26];
string s;
set<int> adj[MM];

void dfs(int u){
    col[u] = 1;
    for(int v : adj[u]){
        if(col[v] == 1){
            cout << "-1\n";
            exit(0);
        }
        if(col[v] == 0) dfs(v);
    }
    col[u] = 2;
}

int main() {
	cin.tie(0)->sync_with_stdio(0);
    cin >> n >> m;
    cin >> s;
    s = "$" + s;
    for(int i = 0; i < m; i++){
        int x,y; cin >> x >> y;
        if(x == y){
            cout << "-1\n";
            return 0;
        }
        adj[x].insert(y); ind[y]++;
    }
    for(int i = 1; i <= n; i++){
        if(col[i] == 0){
            dfs(i);
        }
    }
    queue<int> q;
    for(int i = 1; i <= n; i++){
        if(ind[i] == 0) q.push(i);
    }
    vector<int> topo;
    while(!q.empty()){
        int u = q.front(); q.pop();
        topo.eb(u);
        for(int v : adj[u]){
            if(--ind[v] == 0) q.push(v);
        }
    }
    for(int u : topo){
        dp[u][s[u]-'a']++;
    }

    for(int u : topo){
        for(int v : adj[u]){
            for(int i = 0; i < 26; i++)
                dp[v][i] = max(dp[v][i],dp[u][i] + (i == (s[v]-'a')));
        }
    }
    int ans = 0;
    for(int i = 1; i <= n; i++){
        int cur = 0;
        for(int j = 0; j < 26; j++) cur = max(cur,dp[i][j]);
        ans = max(ans,cur);
    }
    cout << ans << "\n";
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pi = pair<int, int>;
using pll = pair<ll, ll>;
constexpr int INF = 0x3f3f3f3f; constexpr ll LLINF = 0x3f3f3f3f3f3f3f3f;
#define db(x) { cerr << #x << " = " << x << endl; }
template<class RIt> void dbarr(RIt frs, RIt lst){ cerr << "arr: "; for(int i = 0; i < (int)(lst-frs); i++) cerr << frs[i] << " \n"[i==(int)(lst-frs)-1]; }
#define all(x) begin(x), end(x)
#define pb push_back
#define eb emplace_back
#define mpr make_pair
#define fs first
#define sn second
const int MM = 3e5+5;
int n,m,col[MM],ind[MM],dp[MM][26];
string s;
vector<int> adj[MM];

void dfs(int u){
    col[u] = 1;
    for(int v : adj[u]){
        if(col[v] == 1){
            cout << "-1\n";
            exit(0);
        }
        if(col[v] == 0) dfs(v);
    }
    col[u] = 2;
}

int main() {
	cin.tie(0)->sync_with_stdio(0);
    cin >> n >> m;
    cin >> s;
    s = "$" + s;
    for(int i = 0; i < m; i++){
        int x,y; cin >> x >> y;
        adj[x].eb(y); ind[y]++;
    }
    for(int i = 1; i <= n; i++){
        if(col[i] == 0){
            dfs(i);
        }
    }
    queue<int> q;
    for(int i = 1; i <= n; i++){
        if(ind[i] == 0) q.push(i);
    }
    vector<int> topo;
    while(!q.empty()){
        int u = q.front(); q.pop();
        topo.eb(u);
        for(int v : adj[u]){
            if(--ind[v] == 0) q.push(v);
        }
    }
    for(int u : topo){
        dp[u][s[u]-'a']++;
    }

    for(int u : topo){
        for(int v : adj[u]){
            dp[v][s[u]-'a'] = dp[u][s[u]-'a'] + 1;
        }
    }
    int ans = 0;
    for(int i = 1; i <= n; i++){
        int cur = 0;
        for(int j = 0; j < 26; j++) cur = max(cur,dp[i][j]);
        ans = max(ans,cur);
    }
    cout << ans << "\n";
}


#include<iostream>
#include<algorithm>
#include<string>
#include<set>
#include<vector>
#include<map>
using namespace std;
#define ll long long
#define D double
#define LD long double
#define S string
#define m_p make_pair
map <char, ll > m;
bool open(char w) { if (w == '{' || w == '(' || w == '[' || w == '<')return true;else return false; }
char d(char w)
{
	if (w == '}')return '{';
	if (w == ')')return '(';
	if (w == '>')return '<';
	if (w == ']')return '[';
}
int main()
{
	ll n, i, j,a,ans=0,oo=0,cc=0,an=0;
	S s;
	cin >> s;
	if (s.length() % 2 != 0) { cout << "Impossible" << endl;return 0; }
	for (i = 0;i < s.length();i++)
	{
		if (open(s[i]))
		{
			oo++;
			m[s[i]]++;
		}

		else
		{
			cc++;
			if (m[d(s[i])]) { m[d(s[i])]--;an += 2; }
		}
	}
	if (oo != cc) { cout << "Impossible" << endl;return 0; }
	cout <<( s.length()-an)/2<< endl;

	/*int n, a, b, i, j;
	S s;
	cin >> n >> a >> b;
	cin >> s;
	if (n%a == 0)
	{
		cout << n / a << endl;
		for (i = 0;i < n;i += a)cout << s.substr(i, a) << endl;
	}
	else if (n%b == 0)
	{
		cout << n / b << endl;
		for (i = 0;i < n;i += b)cout << s.substr(i, b) << endl;
	}
	else if (n%(a+b) == a)
	{
		int z = (n / (a + b));
		cout << ( (z*2) + 1) << endl;
		for (i = 0;i < (z *(a + b));i += (a + b))
		{
			cout << s.substr(i, a) << endl << s.substr(i + a, b) << endl;
		}
		cout << s.substr(i, a)<<endl;
	}
	else if (n % (a + b) == b)
	{
		int z = (n / (a + b));
		cout << ((z * 2) + 1) << endl;
		for (i = 0;i < (z *(a + b));i += (a + b))
		{
			cout << s.substr(i, a) << endl << s.substr(i + a, b) << endl;
		}
		cout << s.substr(i, b)<<endl;
	}
	else if (n % (a + b) == 0)
	{
		int z = (n / (a + b));
		cout << (z * 2) << endl;
		for (i = 0;i < (z *(a + b));i += (a + b))
		{
			cout << s.substr(i, a) << endl << s.substr(i + a, b) << endl;
		}
	}
	else cout << -1 << endl;

	*/
	//system("pause");
	return 0;

}


#include<iostream>
#include<algorithm>
#include<string>
#include<set>
#include<vector>
#include<map>
using namespace std;
#define ll long long
#define D double
#define LD long double
#define S string
#define m_p make_pair
map <char, ll > m;
bool open(char w) { if (w == '{' || w == '(' || w == '[' || w == '<')return true;else return false; }
char d(char w)
{
	if (w == '}')return '{';
	if (w == ')')return '(';
	if (w == '>')return '<';
	if (w == ']')return '[';
}
int main()
{
	ll n, i, j,a,ans=0,oo=0,cc=0,an=0;
	S s;
	cin >> s;
	if (s.length() % 2 != 0) { cout << "Impossible" << endl;return 0; }
	for (i = 0;i < s.length();i++)
	{
		if (open(s[i]))
		{
			oo++;
			m[s[i]]++;
		}

		else
		{
			cc++;
			if (cc > oo) { cout << "Impossible" << endl;return 0; }
			if (m[d(s[i])])  m[d(s[i])]--;
			else an++;
		}
	}
	if (oo != cc) { cout << "Impossible" << endl;return 0; }
	cout <<an<< endl;

	/*int n, a, b, i, j;
	S s;
	cin >> n >> a >> b;
	cin >> s;
	if (n%a == 0)
	{
		cout << n / a << endl;
		for (i = 0;i < n;i += a)cout << s.substr(i, a) << endl;
	}
	else if (n%b == 0)
	{
		cout << n / b << endl;
		for (i = 0;i < n;i += b)cout << s.substr(i, b) << endl;
	}
	else if (n%(a+b) == a)
	{
		int z = (n / (a + b));
		cout << ( (z*2) + 1) << endl;
		for (i = 0;i < (z *(a + b));i += (a + b))
		{
			cout << s.substr(i, a) << endl << s.substr(i + a, b) << endl;
		}
		cout << s.substr(i, a)<<endl;
	}
	else if (n % (a + b) == b)
	{
		int z = (n / (a + b));
		cout << ((z * 2) + 1) << endl;
		for (i = 0;i < (z *(a + b));i += (a + b))
		{
			cout << s.substr(i, a) << endl << s.substr(i + a, b) << endl;
		}
		cout << s.substr(i, b)<<endl;
	}
	else if (n % (a + b) == 0)
	{
		int z = (n / (a + b));
		cout << (z * 2) << endl;
		for (i = 0;i < (z *(a + b));i += (a + b))
		{
			cout << s.substr(i, a) << endl << s.substr(i + a, b) << endl;
		}
	}
	else cout << -1 << endl;

	*/
	//system("pause");
	return 0;

}


#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define maxn 1000005
char s[maxn];
int vis[10];
int main()
{
    int i, len, res, cnt, cl, op;
    scanf("%s", s);
    len = strlen(s);
    for(i = 0;i < len;i++)
    {
        if(vis[0]>0&&s[i]=='>') vis[0]--;
        else if(vis[1]>0&&s[i]=='}') vis[1]--;
        else if(vis[2]>0&&s[i]==']') vis[2]--;
        else if(vis[3]>0&&s[i]==')') vis[3]--;
        else{
            if(s[i]=='<') vis[0]++;
            if(s[i]=='{') vis[1]++;
            if(s[i]=='[') vis[2]++;
            if(s[i]=='(') vis[3]++;
            if(s[i]=='>') vis[4]++;
            if(s[i]=='}') vis[5]++;
            if(s[i]==']') vis[6]++;
            if(s[i]==')') vis[7]++;
        }
    }
    cnt = op = cl = 0;
    for(i = 0;i < 8;i++){
        if(i <= 3) op += vis[i];
        else cl += vis[i];
        cnt += vis[i];
    }
    if(op != cl)printf("Impossible\n");
    else printf("%d\n", cnt / 2);
}


#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <stack>
using namespace std;
#define maxn 1000005
char s[maxn];
char mapping(char a)
{
    if(a=='{') return '}';
    if(a=='<') return '>';
    if(a=='[') return ']';
    if(a=='(') return ')';
}
int main()
{
    stack<char> st;
    scanf("%s", s);
    int len = strlen(s);
    int ans = 0;
    for(int i = 0;i < len;i++)
    {
        if(s[i]=='<'||s[i]=='{'||s[i]=='['||s[i]=='(') st.push(s[i]);
        else if(!st.empty()){
            if(mapping(st.top()) != s[i])
                ans++;
            st.pop();
        }else{
            printf("Impossible\n");
            return 0;
        }
    }
    printf("%d\n", ans);
}


#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <stack>
using namespace std;
#define maxn 1000005
char s[maxn];
char mapping(char a)
{
    if(a=='{') return '}';
    if(a=='<') return '>';
    if(a=='[') return ']';
    if(a=='(') return ')';
}
int main()
{
    stack<char> st;
    scanf("%s", s);
    int len = strlen(s);
    int ans = 0;
    for(int i = 0;i < len;i++)
    {
        if(s[i]=='<'||s[i]=='{'||s[i]=='['||s[i]=='(') st.push(s[i]);
        else if(!st.empty()){
            if(mapping(st.top()) != s[i])
                ans++;
            st.pop();
        }else{
            printf("Impossible\n");
            return 0;
        }
    }
    if(!st.empty()) printf("Impossible\n");
    printf("%d\n", ans);
}


#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <stack>
using namespace std;
#define maxn 1000005
char s[maxn];
char mapping(char a)
{
    if(a=='{') return '}';
    if(a=='<') return '>';
    if(a=='[') return ']';
    if(a=='(') return ')';
}
int main()
{
    stack<char> st;
    scanf("%s", s);
    int len = strlen(s);
    int ans = 0;
    for(int i = 0;i < len;i++)
    {
        if(s[i]=='<'||s[i]=='{'||s[i]=='['||s[i]=='(') st.push(s[i]);
        else if(!st.empty()){
            if(mapping(st.top()) != s[i])
                ans++;
            st.pop();
        }else{
            printf("Impossible\n");
            return 0;
        }
    }
    if!st.empty()) printf("Impossible\n");
    printf("%d\n", ans);
}


#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <stack>
using namespace std;
#define maxn 1000005
char s[maxn];
char mapping(char a)
{
    if(a=='{') return '}';
    if(a=='<') return '>';
    if(a=='[') return ']';
    if(a=='(') return ')';
}
int main()
{
    stack<char> st;
    scanf("%s", s);
    int len = strlen(s);
    int ans = 0;
    for(int i = 0;i < len;i++)
    {
        if(s[i]=='<'||s[i]=='{'||s[i]=='['||s[i]=='(') st.push(s[i]);
        else if(!st.empty()){
            if(mapping(st.top()) != s[i])
                ans++;
            st.pop();
        }else{
            printf("Impossible\n");
            return 0;
        }
    }
    if(!st.empty()) printf("Impossible\n");
    else printf("%d\n", ans);
}


#include<iostream>
#include<math.h>
using namespace std;
int c(char t){
	if ((t=='<')||(t=='>')||(t=='(')||(t==')')||(t=='{')||(t=='}')||(t=='[')||(t==']')) return 1;
	else return 0;
}
int q(char a){
	switch(a){
		case '<':return 1;break;
		case '{':return 2;break;
		case '(':return 3;break;
		case '[':return 4;break;
		case '>':return -1;break;
		case '}':return -2;break;
		case ')':return -3;break;
		case ']':return -4;break;
	}
}
int main(){
int i,n,k,j=1,ans=0,s=0;
short t[500000];
char a[1000100];
cin>>a;
for (i=0;c(a[i]);i++)
{
	k=q(a[i]);
	if (k>0) {t[j++] = k;s++;} else{
		t[--j] +=k; if (t[j]!=0) ans++; s--;
	}
	if (j<0){cout<<"Impossible";return 0;}
}
if (s!=0){cout<<"Impossible";return 0;}
cout<<ans;
	return 0;
}


#include<iostream>
#include<math.h>
using namespace std;
int c(char t){
	if ((t=='<')||(t=='>')||(t=='(')||(t==')')||(t=='{')||(t=='}')||(t=='[')||(t==']')) return 1;
	else return 0;
}
int q(char a){
	switch(a){
		case '<':return 1;break;
		case '{':return 2;break;
		case '(':return 3;break;
		case '[':return 4;break;
		case '>':return -1;break;
		case '}':return -2;break;
		case ')':return -3;break;
		case ']':return -4;break;
	}
}
int main(){
int i,n,k,j=1,ans=0,s=0;
short t[500000];
char a[1000100];
cin>>a;
for (i=0;c(a[i]);i++)
{
	k=q(a[i]);
	if (k>0) {t[j++] = k;s++;} else{
		t[--j] +=k; if (t[j]!=0) ans++; s--;
	}
	if ((j<0)||(s<0)){cout<<"Impossible";return 0;}
}
if (s!=0){cout<<"Impossible";return 0;}
cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef vector<int> vi;
typedef pair<int,int> pi;
typedef vector<string> vs;
typedef vector<pi> vpi;

#ifdef ONLINE_JUDGE
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#define fi          first
#define se          second
#define mp 			make_pair
#define pb          push_back
#define forall(i,a,b)               for(int i=a;i<b;++i)
#define forlla(i,a,b) for(int (i) = (a); (i) > (b); --(i))
#define foreach(v, c)               for( typeof( (c).begin()) v = (c).begin();  v != (c).end(); ++v)
#define all(a)                      a.begin(), a.end()
#define in(a,b)                     ( (b).find(a) != (b).end())
#define sqr(a)  (((a) * (a)))
#define max(a,b)                    ( (a) > (b) ? (a) : (b))
#define min(a,b)                    ( (a) < (b) ? (a) : (b))
#define mes(a,b)					memset(a,b,sizeof a)
#define endl			    		"\n"
#define ll 							long long
const int oo = 1000000009;
const double eps = 1e-9;
const int mod = 1000000007;

int main(){
	char str[1000001]; scanf("%s",str);
	int ans=0,bal=0,n=strlen(str),a[4];
	memset(a,0,sizeof a);
	forall(i,0,n){
		if(str[i]=='<') {
			++bal;++a[0];
		}
		else if(str[i]=='{') {
			++bal;++a[1];
		}
		else if(str[i]=='['){
			++bal;++a[2];
		}
		else if(str[i]=='('){
			++bal;++a[3];
		}
		else if(str[i]=='>'){
			--bal;--a[0];
		}
		else if(str[i]=='}'){
			--bal;--a[1];
		}
		else if(str[i]==']'){
			--bal;--a[2];
		}
		else if(str[i]==')'){
			--bal;--a[3];
		}
		if(bal < 0) {
			printf("Impossible\n");
			return 0;
		}
	}
	if(bal) printf("Impossible\n");
	else{
		forall(i,0,4){
			if(a[i]>0) ans+=a[i];
		}
		printf("%d\n",ans);
	}
}


#include <bits/stdc++.h>
using namespace std;

typedef vector<int> vi;
typedef pair<int,int> pi;
typedef vector<string> vs;
typedef vector<pi> vpi;

#ifdef ONLINE_JUDGE
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#define fi          first
#define se          second
#define mp 			make_pair
#define pb          push_back
#define forall(i,a,b)               for(int i=a;i<b;++i)
#define forlla(i,a,b) for(int (i) = (a); (i) > (b); --(i))
#define foreach(v, c)               for( typeof( (c).begin()) v = (c).begin();  v != (c).end(); ++v)
#define all(a)                      a.begin(), a.end()
#define in(a,b)                     ( (b).find(a) != (b).end())
#define sqr(a)  (((a) * (a)))
#define max(a,b)                    ( (a) > (b) ? (a) : (b))
#define min(a,b)                    ( (a) < (b) ? (a) : (b))
#define mes(a,b)					memset(a,b,sizeof a)
#define endl			    		"\n"
#define ll 							long long
const int oo = 1000000009;
const double eps = 1e-9;
const int mod = 1000000007;

int main(){
	char str[1000001]; scanf("%s",str);
	int ans=0,bal=0,n=strlen(str),a[4];
	bool pos=false;
	memset(a,0,sizeof a);
	forall(i,0,n){
		if(str[i]=='<') {
			++bal;++a[0];
		}
		else if(str[i]=='{') {
			++bal;++a[1];
		}
		else if(str[i]=='['){
			++bal;++a[2];
		}
		else if(str[i]=='('){
			++bal;++a[3];
		}
		else if(str[i]=='>'){
			--bal;--a[0];
		}
		else if(str[i]=='}'){
			--bal;--a[1];
		}
		else if(str[i]==']'){
			--bal;--a[2];
		}
		else if(str[i]==')'){
			--bal;--a[3];
		}
		if(bal < 0) {
			pos=true;
		}
	}
	if(bal!=0 || pos) printf("Impossible\n");
	else{
		forall(i,0,4){
			if(a[i]>0) ans+=a[i];
		}
		printf("%d\n",ans);
	}
}


#include <bits/stdc++.h>
using namespace std;

typedef vector<int> vi;
typedef pair<int,int> pi;
typedef vector<string> vs;
typedef vector<pi> vpi;

#ifdef ONLINE_JUDGE
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#define fi          first
#define se          second
#define mp 			make_pair
#define pb          push_back
#define forall(i,a,b)               for(int i=a;i<b;++i)
#define forlla(i,a,b) for(int (i) = (a); (i) > (b); --(i))
#define foreach(v, c)               for( typeof( (c).begin()) v = (c).begin();  v != (c).end(); ++v)
#define all(a)                      a.begin(), a.end()
#define in(a,b)                     ( (b).find(a) != (b).end())
#define sqr(a)  (((a) * (a)))
#define max(a,b)                    ( (a) > (b) ? (a) : (b))
#define min(a,b)                    ( (a) < (b) ? (a) : (b))
#define mes(a,b)					memset(a,b,sizeof a)
#define endl			    		"\n"
#define ll 							long long
const int oo = 1000000009;
const double eps = 1e-9;
const int mod = 1000000007;

int main(){
	char str[1000001]; scanf("%s",str);
	int ans=0,bal=0,j=0,n=strlen(str),a[4];
	bool pos=false;
	memset(a,0,sizeof a);
	forall(i,0,n){
		if(str[i]=='<') {
			++bal;j=i;
		}
		else if(str[i]=='{') {
			++bal;j=i;
		}
		else if(str[i]=='['){
			++bal;j=i;
		}
		else if(str[i]=='('){
			++bal;j=i;
		}
		else if(str[i]=='>'){
			--bal;
			if(i && str[j]!='<'){
				++ans;
			}
			--j;
		}
		else if(str[i]=='}'){
			--bal;
			if(i && str[j]!='{'){
				++ans;
			}
			--j;
		}
		else if(str[i]==']'){
			--bal;
			if(i && str[j]!='['){
				++ans;
			}
			--j;
		}
		else if(str[i]==')'){
			--bal;
			if(i && str[j]!='('){
				++ans;
			}
			--j;
		}
		if(bal < 0) {
			pos=true;
		}
	}
	if(bal!=0 || pos) printf("Impossible\n");
	else{
		printf("%d\n",ans);
	}
}


#include <bits/stdc++.h>
using namespace std;

typedef vector<int> vi;
typedef pair<int,int> pi;
typedef vector<string> vs;
typedef vector<pi> vpi;

#ifdef ONLINE_JUDGE
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#define fi          first
#define se          second
#define mp 			make_pair
#define pb          push_back
#define forall(i,a,b)               for(int i=a;i<b;++i)
#define forlla(i,a,b) for(int (i) = (a); (i) > (b); --(i))
#define foreach(v, c)               for( typeof( (c).begin()) v = (c).begin();  v != (c).end(); ++v)
#define all(a)                      a.begin(), a.end()
#define in(a,b)                     ( (b).find(a) != (b).end())
#define sqr(a)  (((a) * (a)))
#define max(a,b)                    ( (a) > (b) ? (a) : (b))
#define min(a,b)                    ( (a) < (b) ? (a) : (b))
#define mes(a,b)					memset(a,b,sizeof a)
#define endl			    		"\n"
#define ll 							long long
const int oo = 1000000009;
const double eps = 1e-9;
const int mod = 1000000007;

int main(){
	char str[1000001]; scanf("%s",str);
	int ans=0,bal=0,n=strlen(str),a[4];
	bool pos=false;
	memset(a,0,sizeof a);
	forall(i,0,n){
		if(str[i]=='<') {
			++bal;++a[0];
		}
		else if(str[i]=='{') {
			++bal;++a[1];
		}
		else if(str[i]=='['){
			++bal;++a[2];
		}
		else if(str[i]=='('){
			++bal;++a[3];
		}
		else if(str[i]=='>'){
			--bal;--a[0];
		}
		else if(str[i]=='}'){
			--bal;--a[1];
		}
		else if(str[i]==']'){
			--bal;--a[2];
		}
		else if(str[i]==')'){
			--bal;--a[3];
		}
		if(bal < 0) {
			pos=true;
		}
	}
	if(bal || pos) printf("Impossible\n");
	else{
		forall(i,0,4){
			if(a[i]>0) ans+=a[i];
		}
		printf("%d\n",ans);
	}
}


#include <bits/stdc++.h>
using namespace std;

typedef vector<int> vi;
typedef pair<int,int> pi;
typedef vector<string> vs;
typedef vector<pi> vpi;

#ifdef ONLINE_JUDGE
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#define fi          first
#define se          second
#define mp 			make_pair
#define pb          push_back
#define forall(i,a,b)               for(int i=a;i<b;++i)
#define forlla(i,a,b) for(int (i) = (a); (i) > (b); --(i))
#define foreach(v, c)               for( typeof( (c).begin()) v = (c).begin();  v != (c).end(); ++v)
#define all(a)                      a.begin(), a.end()
#define in(a,b)                     ( (b).find(a) != (b).end())
#define sqr(a)  (((a) * (a)))
#define max(a,b)                    ( (a) > (b) ? (a) : (b))
#define min(a,b)                    ( (a) < (b) ? (a) : (b))
#define mes(a,b)					memset(a,b,sizeof a)
#define endl			    		"\n"
#define ll 							long long
const int oo = 1000000009;
const double eps = 1e-9;
const int mod = 1000000007;

int main(){
	char str[1000001]; scanf("%s",str);
	int ans=0,n=strlen(str);
	stack<char> mystack;
	forall(i,0,n){
		if(str[i]=='(' || str[i]=='{' || str[i]=='<' || str[i]=='['){
			mystack.push(str[i]);
		}
		else{
			if(mystack.empty()){
				printf("Impossible\n");
				return 0;
			}
			else{
				char s=mystack.top();
				if(str[i]==')' && s!='(') ++ans;
				else if(str[i]==']' && s!='[') ++ans;
				else if(str[i]=='}' && s!='{') ++ans;
				else if(str[i]=='>' && s!='<') ++ans;
				mystack.pop();
			}
		}
	}
	if(mystack.empty()) printf("%d\n",ans);
	else printf("Impossible\n");
}


#include <bits/stdc++.h>
using namespace std;

typedef vector<int> vi;
typedef pair<int,int> pi;
typedef vector<string> vs;
typedef vector<pi> vpi;

#ifdef ONLINE_JUDGE
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#define fi          first
#define se          second
#define mp 			make_pair
#define pb          push_back
#define forall(i,a,b)               for(int i=a;i<b;++i)
#define forlla(i,a,b) for(int (i) = (a); (i) > (b); --(i))
#define foreach(v, c)               for( typeof( (c).begin()) v = (c).begin();  v != (c).end(); ++v)
#define all(a)                      a.begin(), a.end()
#define in(a,b)                     ( (b).find(a) != (b).end())
#define sqr(a)  (((a) * (a)))
#define max(a,b)                    ( (a) > (b) ? (a) : (b))
#define min(a,b)                    ( (a) < (b) ? (a) : (b))
#define mes(a,b)					memset(a,b,sizeof a)
#define endl			    		"\n"
#define ll 							long long
const int oo = 1000000009;
const double eps = 1e-9;
const int mod = 1000000007;

int main(){
	char str[1000001]; scanf("%s",str);
	int ans=0,n=strlen(str);
	stack<char> mystack;
	forall(i,0,n){
		if(str[i]=='(' || str[i]=='{' || str[i]=='<' || str[i]=='['){
			mystack.push(str[i]);
		}
		else{
			if(mystack.empty()){
				printf("Impossible\n");
				return 0;
			}
			else{
				char s=mystack.top();
				if(str[i]==')' && s!='(') ++ans;
				else if(str[i]==']' && s!='[') ++ans;
				else if(str[i]=='}' && s!='{') ++ans;
				else if(str[i]=='>' && s!='<') ++ans;
				mystack.pop();
			}
		}
	}
	printf("%d\n",ans);
}


#include <bits/stdc++.h>
using namespace std;

typedef vector<int> vi;
typedef pair<int,int> pi;
typedef vector<string> vs;
typedef vector<pi> vpi;

#ifdef ONLINE_JUDGE
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#define fi          first
#define se          second
#define mp 			make_pair
#define pb          push_back
#define forall(i,a,b)               for(int i=a;i<b;++i)
#define forlla(i,a,b) for(int (i) = (a); (i) > (b); --(i))
#define foreach(v, c)               for( typeof( (c).begin()) v = (c).begin();  v != (c).end(); ++v)
#define all(a)                      a.begin(), a.end()
#define in(a,b)                     ( (b).find(a) != (b).end())
#define sqr(a)  (((a) * (a)))
#define max(a,b)                    ( (a) > (b) ? (a) : (b))
#define min(a,b)                    ( (a) < (b) ? (a) : (b))
#define mes(a,b)					memset(a,b,sizeof a)
#define endl			    		"\n"
#define ll 							long long
const int oo = 1000000009;
const double eps = 1e-9;
const int mod = 1000000007;

int main(){
	char str[1000001]; scanf("%s",str);
	int ans=0,bal=0,j=0,n=strlen(str),a[4];
	bool pos=false;
	memset(a,0,sizeof a);
	forall(i,0,n){
		if(str[i]=='<' || str[i]=='{' || str[i]=='[' || str[i]=='(') {
			++bal;j=i;
		}
		else if(str[i]=='>'){
			if(j>=0 && str[j]!='<'){
				++ans;
			}
			--bal;--j;
		}
		else if(str[i]=='}'){
			if(j>=0 && str[j]!='{'){
				++ans;
			}
			--bal;--j;
		}
		else if(str[i]==']'){
			if(j>=0 && str[j]!='['){
				++ans;
			}
			--bal;--j;
		}
		else if(str[i]==')'){
			if(j>=0 && str[j]!='('){
				++ans;
			}
			--bal;--j;
		}
		if(bal < 0) {
			pos=true;
			break;
		}
	}
	if(bal!=0 || pos) printf("Impossible\n");
	else{
		printf("%d\n",ans);
	}
}


/*
Raj Manvar [rajmanvar]
LANG: C++
 */
#include <bits/stdc++.h>
#include <unistd.h>
#define PB push_back
#define MP make_pair
#define F first
#define S second
#define SZ(a) (int)(a.size())
#define SET(a,b) memset(a,b,sizeof(a))
#define LET(x,a) __typeof(a) x(a)
#define TR(v,it) for( LET(it,v.begin()) ; it != v.end() ; it++)
#define loop(i,a,b) for(int i=a;i<b;i++)
#define si(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define sortv(a) sort(a.begin(),a.end())
#define all(a) a.begin(),a.end()
#define bitcount(n) __builtin_popcount(n)
#define DRT()  int t; cin>>t; while(t--)
#define TRACE
#ifdef TRACE
#define trace1(x)                cerr << #x << ": " << x << endl;
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;
#define trace5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
#define trace6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;
#else
#define trace1(x)
#define trace2(x, y)
#define trace3(x, y, z)
#define trace4(a, b, c, d)
#define trace5(a, b, c, d, e)
#define trace6(a, b, c, d, e, f)
#endif
using namespace std;
typedef long long int lli;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector< vi > vvi;
typedef vector< ii > vii;
int main()
{
  string a;
  int o=0,ot1=0,ct1=0,ot2=0,ct2=0,ot3=0,ct3=0,ot4=0,ct4=0;
  cin>>a;
  loop(i,0,a.size())
  {
    if(a[i]=='(') { o++; ot1++; }   //1
    else if(a[i]=='<') {o++;  ot2++; }   //2
    else if(a[i]=='{')  {o++;  ot3++; } //3
    else if(a[i]=='[')   { o++; ot4++; } //4
    else if(a[i]==')') { o--; ct1++; } //1
    else if(a[i]=='>')  { o--; ct2++; }//2
    else if(a[i]=='}')  {o--;  ct3++; } //3
    else if(a[i]==']') { o--;  ct4++;} //4
  }
  if(o!=0) cout<<-1<<endl;
  else
  {
    int ans=abs(ot1-ct1)+abs(ot2-ct2)+abs(ot3-ct3)+abs(ot4-ct4);
    cout<<ans/2<<endl;
  }
}


/*
Raj Manvar [rajmanvar]
LANG: C++
 */
#include <bits/stdc++.h>
#include <unistd.h>
#define PB push_back
#define MP make_pair
#define F first
#define S second
#define SZ(a) (int)(a.size())
#define SET(a,b) memset(a,b,sizeof(a))
#define LET(x,a) __typeof(a) x(a)
#define TR(v,it) for( LET(it,v.begin()) ; it != v.end() ; it++)
#define loop(i,a,b) for(int i=a;i<b;i++)
#define si(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define sortv(a) sort(a.begin(),a.end())
#define all(a) a.begin(),a.end()
#define bitcount(n) __builtin_popcount(n)
#define DRT()  int t; cin>>t; while(t--)
#define TRACE
#ifdef TRACE
#define trace1(x)                cerr << #x << ": " << x << endl;
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;
#define trace5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
#define trace6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;
#else
#define trace1(x)
#define trace2(x, y)
#define trace3(x, y, z)
#define trace4(a, b, c, d)
#define trace5(a, b, c, d, e)
#define trace6(a, b, c, d, e, f)
#endif
using namespace std;
typedef long long int lli;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector< vi > vvi;
typedef vector< ii > vii;
int main()
{
  string a;
  int o=0,ot1=0,ct1=0,ot2=0,ct2=0,ot3=0,ct3=0,ot4=0,ct4=0;
  stack<char> raj;
  cin>>a;
  int flag=0;
  int ans=0;
  loop(i,0,a.size())
  {
    if(a[i]=='(')      {raj.push('('); o++; ot1++; }   //1
    else if(a[i]=='<') {raj.push('<');o++;  ot2++; }   //2
    else if(a[i]=='{') {raj.push('{');o++;  ot3++; } //3
    else if(a[i]=='[') {raj.push('['); o++; ot4++; } //4
    else if(a[i]==')') {if(raj.size()==0){cout<<"Impossible"<<endl; return 0;} if(raj.top()=='(') {raj.pop();} else {raj.pop(); ans++;} o--; ct1++; } //1
    else if(a[i]=='>') {if(raj.size()==0){cout<<"Impossible"<<endl; return 0;}if(raj.top()=='<') {raj.pop();} else {raj.pop(); ans++;} o--; ct2++; }//2
    else if(a[i]=='}') {if(raj.size()==0){cout<<"Impossible"<<endl; return 0;}if(raj.top()=='{') {raj.pop();} else {raj.pop(); ans++;}o--;  ct3++; } //3
    else if(a[i]==']') {if(raj.size()==0){cout<<"Impossible"<<endl; return 0;}if(raj.top()=='[') {raj.pop();} else {raj.pop(); ans++;} o--;  ct4++;} //4
    if(o<0) flag=1;
    //trace2(i,ans);
  }
  if(raj.size()!=0) {cout<<"Impossible"<<endl; return 0;}
  else cout<<ans<<endl;
  // if(o!=0 || flag==1) cout<<"Impossible"<<endl;
  // else
  // {
  //   int ans=abs(ot1-ct1)+abs(ot2-ct2)+abs(ot3-ct3)+abs(ot4-ct4);
  //   cout<<ans/2<<endl;
  // }
}


/*
Raj Manvar [rajmanvar]
LANG: C++
 */
#include <bits/stdc++.h>
#include <unistd.h>
#define PB push_back
#define MP make_pair
#define F first
#define S second
#define SZ(a) (int)(a.size())
#define SET(a,b) memset(a,b,sizeof(a))
#define LET(x,a) __typeof(a) x(a)
#define TR(v,it) for( LET(it,v.begin()) ; it != v.end() ; it++)
#define loop(i,a,b) for(int i=a;i<b;i++)
#define si(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define sortv(a) sort(a.begin(),a.end())
#define all(a) a.begin(),a.end()
#define bitcount(n) __builtin_popcount(n)
#define DRT()  int t; cin>>t; while(t--)
#define TRACE
#ifdef TRACE
#define trace1(x)                cerr << #x << ": " << x << endl;
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;
#define trace5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
#define trace6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;
#else
#define trace1(x)
#define trace2(x, y)
#define trace3(x, y, z)
#define trace4(a, b, c, d)
#define trace5(a, b, c, d, e)
#define trace6(a, b, c, d, e, f)
#endif
using namespace std;
typedef long long int lli;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector< vi > vvi;
typedef vector< ii > vii;
int main()
{
  string a;
  int o=0,ot1=0,ct1=0,ot2=0,ct2=0,ot3=0,ct3=0,ot4=0,ct4=0;
  stack<char> raj;
  cin>>a;
  int flag=0;
  int ans=0;
  loop(i,0,a.size())
  {
    if(a[i]=='(')      {raj.push('('); o++; ot1++; }   //1
    else if(a[i]=='<') {raj.push('<');o++;  ot2++; }   //2
    else if(a[i]=='{') {raj.push('{');o++;  ot3++; } //3
    else if(a[i]=='[') {raj.push('['); o++; ot4++; } //4
    else if(a[i]==')') {if(raj.size()==0){cout<<"Imposible"<<endl; return 0;} if(raj.top()=='(') {raj.pop();} else {raj.pop(); ans++;} o--; ct1++; } //1
    else if(a[i]=='>') {if(raj.size()==0){cout<<"Imposible"<<endl; return 0;}if(raj.top()=='<') {raj.pop();} else {raj.pop(); ans++;} o--; ct2++; }//2
    else if(a[i]=='}') {if(raj.size()==0){cout<<"Imposible"<<endl; return 0;}if(raj.top()=='{') {raj.pop();} else {raj.pop(); ans++;}o--;  ct3++; } //3
    else if(a[i]==']') {if(raj.size()==0){cout<<"Imposible"<<endl; return 0;}if(raj.top()=='[') {raj.pop();} else {raj.pop(); ans++;} o--;  ct4++;} //4
    if(o<0) flag=1;
    //trace2(i,ans);
  }
  if(raj.size()!=0) {cout<<"Impossible"<<endl; return 0;}
  else cout<<ans<<endl;
  // if(o!=0 || flag==1) cout<<"Impossible"<<endl;
  // else
  // {
  //   int ans=abs(ot1-ct1)+abs(ot2-ct2)+abs(ot3-ct3)+abs(ot4-ct4);
  //   cout<<ans/2<<endl;
  // }
}


/*
Raj Manvar [rajmanvar]
LANG: C++
 */
#include <bits/stdc++.h>
#include <unistd.h>
#define PB push_back
#define MP make_pair
#define F first
#define S second
#define SZ(a) (int)(a.size())
#define SET(a,b) memset(a,b,sizeof(a))
#define LET(x,a) __typeof(a) x(a)
#define TR(v,it) for( LET(it,v.begin()) ; it != v.end() ; it++)
#define loop(i,a,b) for(int i=a;i<b;i++)
#define si(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define sortv(a) sort(a.begin(),a.end())
#define all(a) a.begin(),a.end()
#define bitcount(n) __builtin_popcount(n)
#define DRT()  int t; cin>>t; while(t--)
#define TRACE
#ifdef TRACE
#define trace1(x)                cerr << #x << ": " << x << endl;
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;
#define trace5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
#define trace6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;
#else
#define trace1(x)
#define trace2(x, y)
#define trace3(x, y, z)
#define trace4(a, b, c, d)
#define trace5(a, b, c, d, e)
#define trace6(a, b, c, d, e, f)
#endif
using namespace std;
typedef long long int lli;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector< vi > vvi;
typedef vector< ii > vii;
int main()
{
  string a;
  int o=0,ot1=0,ct1=0,ot2=0,ct2=0,ot3=0,ct3=0,ot4=0,ct4=0;
  cin>>a;
  int flag=0;
  loop(i,0,a.size())
  {
    if(a[i]=='(') { o++; ot1++; }   //1
    else if(a[i]=='<') {o++;  ot2++; }   //2
    else if(a[i]=='{')  {o++;  ot3++; } //3
    else if(a[i]=='[')   { o++; ot4++; } //4
    else if(a[i]==')') { o--; ct1++; } //1
    else if(a[i]=='>')  { o--; ct2++; }//2
    else if(a[i]=='}')  {o--;  ct3++; } //3
    else if(a[i]==']') { o--;  ct4++;} //4
    if(o<0) flag=1;
  }
  if(o!=0 || flag==1) cout<<"Impossible"<<endl;
  else
  {
    int ans=abs(ot1-ct1)+abs(ot2-ct2)+abs(ot3-ct3)+abs(ot4-ct4);
    cout<<ans/2<<endl;
  }
}


/*
Raj Manvar [rajmanvar]
LANG: C++
 */
#include <bits/stdc++.h>
#include <unistd.h>
#define PB push_back
#define MP make_pair
#define F first
#define S second
#define SZ(a) (int)(a.size())
#define SET(a,b) memset(a,b,sizeof(a))
#define LET(x,a) __typeof(a) x(a)
#define TR(v,it) for( LET(it,v.begin()) ; it != v.end() ; it++)
#define loop(i,a,b) for(int i=a;i<b;i++)
#define si(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define sortv(a) sort(a.begin(),a.end())
#define all(a) a.begin(),a.end()
#define bitcount(n) __builtin_popcount(n)
#define DRT()  int t; cin>>t; while(t--)
#define TRACE
#ifdef TRACE
#define trace1(x)                cerr << #x << ": " << x << endl;
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;
#define trace5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
#define trace6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;
#else
#define trace1(x)
#define trace2(x, y)
#define trace3(x, y, z)
#define trace4(a, b, c, d)
#define trace5(a, b, c, d, e)
#define trace6(a, b, c, d, e, f)
#endif
using namespace std;
typedef long long int lli;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector< vi > vvi;
typedef vector< ii > vii;
int main()
{
  string a;
  int o=0,ot1=0,ct1=0,ot2=0,ct2=0,ot3=0,ct3=0,ot4=0,ct4=0;
  cin>>a;
  loop(i,0,a.size())
  {
    if(a[i]=='(') { o++; ot1++; }   //1
    else if(a[i]=='<') {o++;  ot2++; }   //2
    else if(a[i]=='{')  {o++;  ot3++; } //3
    else if(a[i]=='[')   { o++; ot4++; } //4
    else if(a[i]==')') { o--; ct1++; } //1
    else if(a[i]=='>')  { o--; ct2++; }//2
    else if(a[i]=='}')  {o--;  ct3++; } //3
    else if(a[i]==']') { o--;  ct4++;} //4
  }
  if(o!=0) cout<<"Impossible"<<endl;
  else
  {
    int ans=abs(ot1-ct1)+abs(ot2-ct2)+abs(ot3-ct3)+abs(ot4-ct4);
    cout<<ans/2<<endl;
  }
}


#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<iostream>
char a[1000005*2];
#include<map>
#include<stack>
using namespace std;
typedef long long ll;
int main(void)
{
    int n,i,k,p,q,m,j,l;
    while(scanf("%s",a)!=EOF)
    {
        map<char,int>my;
        my['<']=1;
        my['>']=5;
        my['{']=2;
        my['}']=6;
        my['(']=3;
        my[')']=7;
        my['[']=4;
        my[']']=8;
        stack<int>st;
        int l=strlen(a);
        if(l%2!=0)
        {
            printf("Impossible\n");
        }
        else
        {

            {
               int cnt=0;int vv=0;
                for(i=0; i<l;i++)
                {
                    if(my[a[i]]<=4)
                    {
                        st.push(my[a[i]]);
                    }
                    else
                    {
                        if(st.empty())
                        {vv=1;
                            break;
                        }
                        else
                        {
                            int cc=st.top();

                            if(my[a[i]]-cc!=4)
                            {
                                cnt++;
                            }
                            st.pop();
                        }
                    }

                }if(vv==0&&st.empty())
                printf("%d\n",cnt);
                else printf("Impossible\n");
            }
        }
    }
    return 0;
}


#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<iostream>
char a[1000005*2];
#include<map>
using namespace std;
typedef long long ll;
int main(void)
{
    int n,i,k,p,q,m,j,l;
    while(scanf("%s",a)!=EOF)
    {
        map<char,int>my;
        my['<']=1;
        my['>']=5;
        my['{']=2;
        my['}']=6;
        my['(']=3;
        my[')']=7;
        my['[']=4;
        my[']']=8;
        int l=strlen(a);
        if(l%2!=0)
        {
            printf("Impossible\n");
        }
        else
        {
            int cnt=0;
            int cnt2=0;
            for(i=0; i<l; i++)
            {

                if(a[i]=='<'||a[i]=='('||a[i]=='{'||a[i]=='[')
                {
                    cnt++;
                }
                else
                {
                    cnt--;
                }
                if(cnt<0)
                    break;

            }
            if(i!=l)
            {
                printf("Impossible\n");
            }
            else
            {
                 cnt=0;
                for(i=1; i<l;)
                {
                    if(my[a[i]]>4)
                    {
                        int vv=i-1;
                        for(j=i; my[a[j]]>4; j++)
                        {
                            if(my[a[j]]-my[a[vv]]!=4)
                            {
                                cnt++;
                            }
                            vv--;

                        }
                        i=j;
                    }
                    else i++;

                }
                printf("%d\n",cnt);
            }
        }
    }
    return 0;
}
close