1 #include<set>
2 #include<queue>
3 #include<cstdio>
4 #include<cstdlib>
5 #include<cstring>
6 #include<iostream>
7 #include<algorithm>
8 using namespace std;
9 const int N = 10;
10 #define For(i,n) for(int i=1;i<=n;i++)
11 #define Rep(i,l,r) for(int i=l;i<=r;i++)
12
13 struct states{
14 int A[N][N];
15 }now,load[N],tmp;
16 bool flag;
17 int n,v;
18 int tot[N<<1],ttot[N][N<<1];
19 int ans[N][4];
20
21 void init(){
22 scanf("%d",&n);
23 For(i,5){
24 while(scanf("%d",&v),v){
25 now.A[i][++now.A[i][0]]=v;
26 tot[v]++;
27 }
28 }
29 }
30
31 void fall(){
32 int k;
33 For(i,5)
34 Rep(j,2,7)
35 if(now.A[i][j]&&!now.A[i][j-1]){
36 for(k=j-1;!now.A[i][k]&&k>=1;k--); ++k;
37 swap(now.A[i][j],now.A[i][k]);
38 }
39 }
40
41 void remark(){
42 For(i,5)
43 For(j,7)
44 if(now.A[i][j]){
45 if(now.A[i][j]==now.A[i][j+1]&&now.A[i][j]==now.A[i][j-1]) tmp.A[i][j]=tmp.A[i][j-1]=tmp.A[i][j+1]=1;
46 if(now.A[i][j]==now.A[i+1][j]&&now.A[i][j]==now.A[i-1][j]) tmp.A[i][j]=tmp.A[i-1][j]=tmp.A[i+1][j]=1;
47 }
48 }
49
50 void clean(){
51 remark();
52 bool ref=false;
53 For(i,5)
54 For(j,7)
55 if(tmp.A[i][j]){
56 tmp.A[i][j]=0;
57 tot[now.A[i][j]]--;
58 now.A[i][j]=0;
59 ref=true;
60 }
61 if(ref){
62 fall();
63 clean();
64 }
65 }
66
67 void move(int i,int j,int g){
68 swap(now.A[i][j],now.A[i+g][j]);
69 fall();
70 clean();
71 }
72
73 bool check(){
74 int cnt=0;
75 For(i,10) if(tot[i]) cnt+=tot[i];
76 return (!cnt);
77 }
78
79 void dfs(int step){
80 if(flag) return;
81 if(step>n){
82 flag=check();
83 return;
84 }
85 load[step]=now;
86 For(i,10) ttot[step][i]=tot[i];
87 For(i,5)
88 For(j,7)
89 for(int k=1;k>=-1&&now.A[i][j];k-=2){
90 if((k==-1&&now.A[i-1][j])||(now.A[i+k][j]==now.A[i][j])) continue;//tree-pruning
91 ans[step][1]=i-1;ans[step][2]=j-1;ans[step][3]=k;
92 move(i,j,k);
93 dfs(step+1);
94 if(flag) return;
95 now=load[step];
96 For(sb,10) tot[sb]=ttot[step][sb];
97 }
98 }
99
100 int main(){
101 init();
102 dfs(1);
103 if(flag) For(i,n) printf("%d %d %d\n",ans[i][1],ans[i][2],ans[i][3]);
104 else puts("-1");
105 return 0;
106 }