#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#define pb push_back
#define inf 0x3f3f3f3f
using namespace std;
namespace INPUT{
char buf[1<<20],*p1,*p2;
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
}
using namespace INPUT;
template<typename T>
inline T read(){
T x=0,p=1;
char ch=gc();
for(;ch<'0'||ch>'9';ch=gc())
if(ch=='-') p=-1;
for(;ch>='0'&&ch<='9';ch=gc())
x=(x<<3)+(x<<1)+(ch^48);
return x*p;
}
const int N=55,M=N*3;
struct Edge{
int u,v;
int cap,flow;
Edge(int u,int v,int cap,int flow):
u(u),v(v),cap(cap),flow(flow){};
};
vector<Edge>edges;
vector<int>G[M];
void AddEdge(int u,int v,int cap){
edges.pb(Edge(u,v,cap,0));
edges.pb(Edge(v,u,0,0));
int m=edges.size();
G[u].pb(m-2),G[v].pb(m-1);
}
bool vis[M];
int d[M];
int src,des;
bool BFS(){
queue<int>q;
memset(vis,0,sizeof(vis));
memset(d,inf,sizeof(d));
q.push(src),d[src]=0,vis[src]=true;
while(!q.empty()){
int u=q.front();
q.pop();
for(auto i:G[u]){
Edge& ed=edges[i];
if(!vis[ed.v]&&ed.cap>ed.flow){
d[ed.v]=d[u]+1;
q.push(ed.v),vis[ed.v]=true;
}
}
}
return vis[des];
}
int cur[M];
int dinic(int u,int a){
if(u==des||a==0) return a;
int flow=0,f;
for(int& i=cur[u];i<G[u].size();i++){
int x=G[u][i];
Edge& ed=edges[x];
if(d[ed.v]==d[u]+1&&(f=dinic(ed.v,min(a,ed.cap-ed.flow)))>0){
edges[x].flow+=f,edges[x^1].flow-=f;
flow+=f,a-=f;
if(!a) break;
}
}
return flow;
}
int Maxflow(){
int flow=0;
while(BFS()){
memset(cur,0,sizeof(cur));
flow+=dinic(src,inf);
}
return flow;
}
int n,k;
int main(){
freopen("P3153.in","r",stdin);
freopen("P3153.out","w",stdout);
n=read<int>(),k=read<int>();
src=0,des=3*n+1;
for(int i=1;i<=n;i++) AddEdge(src,i,0),AddEdge(i,n+i,k),AddEdge(n*2+i,des,0);
char ch='?';
for(int i=1;i<=n;i++){
while(ch!='Y'&&ch!='N') ch=gc();
for(int j=1;j<=n;j++) {
if(ch=='Y') AddEdge(i,n*2+j,1);
else AddEdge(n+i,n*2+j,1);
ch=gc();
}
}
int c=0,flow;
do{
for(auto i:G[src]) edges[i].cap++;
for(auto i:G[des]) edges[i^1].cap++;
flow=Maxflow();
}while(flow==n&&++c);
cout<<c<<endl;
}