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

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/trie_policy.hpp>

using namespace __gnu_pbds;

///#define int long long
#pragma GCC optimize ("O3")
#define ll long long
#define vi vector <int>
#define vii vector <pair<int,int> >
#define rep(i,a,b) for (int i=a;i<b;i++)
#define repD(i,a,b) for (int i=a;i>b;i--)
#define pb push_back
#define pii pair <int,int>
#define mp make_pair
#define ff first
#define ss second
#define all(a) a.begin(),a.end()
#define maa 1000000007
#define Eps 1e-9
#define PI 3.14159265359

typedef tree<int,null_type,less <int>,rb_tree_tag,tree_order_statistics_node_update>ind_set;
///*X.find_by_order("index")
///X.order_of_key("key")

///----------------------------------------------------------------------------------

int n,p,A[20][20],cost[20];
string S;
vii ind[20];
int NP[1<<20];
int ALLTAKEN;
int DP[1<<20];
bool valid(int mask)
{
    return !(NP[mask]==1);
}
void fill(int mask,int i,int j,int ind=0)
{
    ///if (NP[mask]!=-1)return;
    ///NP[mask]=0;
    if (ind==p)
    {
        NP[mask]=1;
        return;
    }
    if (ind==i||ind==j)fill(mask,i,j,ind+1);
    else
    {
        fill(mask,i,j,ind+1);
        fill(mask|(1<<ind),i,j,ind+1);
    }
}
int fun(int mask=0)
{
    if (mask==ALLTAKEN)return 0;
    if (DP[mask]!=-1)return DP[mask];
    int ret=0;
    rep(i,0,p)
    {
        if ((mask&(1<<i))==0 &&valid(mask|(1<<i)))
            ret=max(ret,cost[i]+fun((mask|(1<<i))));
    }
    return DP[mask]=ret;
}
void solve()
{
    rep(i,0,(1<<17))NP[i]=false,DP[i]=-1;
    cin>>n>>p>>S;
    rep(i,0,n)ind[S[i]-'a'].pb({i,S[i]-'a'}),cost[S[i]-'a']++;
    ALLTAKEN=(1<<p)-1;
    rep(i,0,p)rep(j,0,p)cin>>A[i][j];

    vii temp;
    vi maskarray;
    rep(i,0,p)
    {
        if (A[i][i]==0)
        {
            temp=ind[i];
            if (temp.size()<1)
                continue;
            int mask;
            rep(k,0,temp.size()-1)
            {
                mask=0;
                rep(l,temp[k].ff+1,temp[k+1].ff)mask|=(1<<(S[l]-'a'));
                //NP[mask]=true;
                fill(mask,i,i);
            }

            /*rep(k,1,(1<<p))
            {
                for (auto x:maskarray)
                {
                    int T=k;
                    T&=(~(1<<i));
                    rep(l,0,p)
                    {
                        if (x&(1<<l))
                            T|=(1<<l);
                    }
                    NP[T]=true;
                }

            }*/
        }

        rep(j,i+1,p)
        {
            if(A[i][j]==0)
            {

                temp.clear();
                merge(all(ind[i]),all(ind[j]),back_inserter(temp));
                ///   for (auto x:temp)cout<<x.ff<<" ";cout<<"\n";
                if (temp.size()<=1)
                    continue;
                int mask;

                rep(k,0,temp.size()-1)
                {
                    if (temp[k].ss!=temp[k+1].ss)
                    {
                        int mask;
                        rep(k,0,temp.size()-1)
                        {
                            mask=0;
                            rep(l,temp[k].ff+1,temp[k+1].ff)mask|=(1<<(S[l]-'a'));
                           // NP[mask]=true;
                            fill(mask,i,j);
                        }
                    }
                }
                /*rep(k,1,(1<<p))
                {
                    for (auto x:maskarray)
                    {
                        int T=k;
                        T&=(~(1<<i));
                        T&=(~(1<<j));
                        rep(l,0,p)
                        {
                            if (x&(1<<l))
                                T|=(1<<l);
                        }
                        NP[T]=true;
                    }

                }*/
            }
        }
    }

   /// rep(i,0,(1<<p))if (NP[i])cout<<bitset<8>(i)<<"\n";
    cout<<n-fun();


}
signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

///freopen("input.txt","r",stdin);
///freopen("output.txt","w",stdout);

    int t=1;
///cin>>t;
    rep(a,0,t)
    {
        ///cout<<"Case "<<a+1<<": ";
        solve();
    }
}

