考虑二分答案
把男女生都拆点,拆成喜欢和不喜欢
(S)向男生喜欢连边,容量(mid),男生喜欢向不喜欢连边,容量(k),女生同理
然后男生喜欢向女生喜欢连边,男生不喜欢向女生不喜欢连边
然后跑一遍最大流看是否满流即可
//minamoto
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(R int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
#define gg(u) for(R int &i=cur[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
const int N=1005,M=100005;
struct eg{int v,nx,w;}e[M];int head[N],tot=1;
inline void add(R int u,R int v,R int w){
e[++tot]={v,head[u],w},head[u]=tot;
e[++tot]={u,head[v],0},head[v]=tot;
}
int n,dep[N],cur[N],S,T,q[N],hh[N],res,k,h,t,l,r,mid,ans;char s[N];
bool bfs(){
fp(i,S,T)cur[i]=head[i],dep[i]=-1;
q[h=t=1]=S,dep[S]=0;
while(h<=t){
int u=q[h++];
go(u)if(e[i].w&&dep[v]<0){
dep[v]=dep[u]+1,q[++t]=v;
if(v==T)return true;
}
}return false;
}
int dfs(int u,int lim){
if(u==T||!lim)return lim;
int flow=0,f;
gg(u)if(dep[v]==dep[u]+1&&(f=dfs(v,min(lim,e[i].w)))){
flow+=f,lim-=f;
e[i].w-=f,e[i^1].w+=f;
if(!lim)break;
}return flow;
}
int dinic(){int flow=0;while(bfs())flow+=dfs(S,inf);return flow;}
bool check(){
fp(i,S,T)head[i]=hh[i];tot=res;for(R int i=2;i<=tot;i+=2)e[i].w+=e[i^1].w,e[i^1].w=0;
fp(i,1,n)add(S,i,mid);fp(i,1,n)add(i+2*n,T,mid);
return dinic()==mid*n;
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d%d",&n,&k),S=0,T=4*n+1;
fp(i,1,n){
scanf("%s",s+1);
fp(j,1,n)s[j]=='Y'?add(i,j+2*n,1):add(i+n,j+3*n,1);
}if(k){
fp(i,1,n)add(i,i+n,k);fp(i,1,n)add(i+3*n,i+2*n,k);
}fp(i,S,T)hh[i]=head[i];res=tot;
l=0,r=n;
while(l<=r){
mid=(l+r)>>1;
check()?(ans=mid,l=mid+1):(r=mid-1);
}printf("%d
",ans);return 0;
}