/*
分析:
苍天呐~,ac了- -,1WA囧~,二分匹配的水题。
线性代数里面学的么,如果存在ans,那么只交换行、
或只交换列都能抵达ans状态。
所以两个集合,一个是行1(固定不变的行,相当于
固定的座位)、另一个是行2(将初始时候的每一个元素
行编号为多少多少,相当于同学);
那么,如果编号为y童鞋可以坐在编号为x的行上面,
那么就立x到y的一条边。
然后就是二分匹配了。中午了,起床吃早饭去。。囧~~~
2013-03-02
*/
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#define N 111
int n;
int map[N][N];
struct Eage{
int to,next;
}eage[N*N];
int tot,head[N];
void add(int a,int b){
eage[tot].to=b;eage[tot].next=head[a];head[a]=tot++;
}
int match[N],visit[N];
int dfs(int k)
{
int j,v;
for(j=head[k];j!=-1;j=eage[j].next)
{
v=eage[j].to;
if(visit[v]) continue;
visit[v]=1;
if(match[v]==-1 || dfs(match[v]))
{
match[v]=k;
return 1;
}
}
return 0;
}
int main()
{
int i,l,j,v;
int tt,step;
while(scanf("%d",&n)!=-1)
{
memset(match,-1,sizeof(match));
for(i=1;i<=n;i++)
{
for(l=1;l<=n;l++) scanf("%d",&map[i][l]);
if(map[i][i]) match[i]=i;
}
tot=0;
memset(head,-1,sizeof(head));
for(i=1;i<=n;i++)for(l=1;l<=n;l++)
if(map[l][i]) add(i,l);
for(i=1;i<=n;i++)
{
tt=0;
for(j=head[i];j!=-1;j=eage[j].next)
{
v=eage[j].to;
if(match[v]==i) {tt=1;break;}
}
if(tt) continue;
memset(visit,0,sizeof(visit));
dfs(i);
}
int flag=0;
for(i=1;i<=n;i++) if(match[i]==-1) {flag=1;break;}
if(flag) {printf("-1\n");continue;}
step=0;
int temp[N];
struct ANS{
int a,b;
}ans[N];
for(i=1;i<=n;i++) temp[i]=i;
for(i=1;i<=n;i++)
{
for(l=1;l<=n;l++)
{
if(match[l]==i)
{
if(temp[l]==i) break;
for(int j=1;j<=n;j++) if(temp[j]==i) break;
ans[step].a=i;
ans[step].b=temp[l];
temp[j]=temp[l];
temp[l]=i;
step++;
break;
}
}
}
printf("%d\n",step);
for(i=0;i<step;i++) printf("R %d %d\n",ans[i].a,ans[i].b);
}
return 0;
}