#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cassert>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <complex>
#include <stack>
#include <queue>
#include <list>
#include <set>
#include <map>
#include <bitset>
#include <functional>
#include <iterator>

using namespace std;

#define dump(n) cout<<"# "<<#n<<'='<<(n)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define iter(c) __typeof__((c).begin())
#define foreach(i,c) for(iter(c) i=(c).begin();i!=(c).end();++i)
#define all(c) (c).begin(),(c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int,int> pii;

const int INFTY=1<<29;
const double EPS=1e-9;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}
template<typename T>
ostream& operator<<(ostream& os,const vector<T>& a){
	os<<'[';
	rep(i,a.size()) os<<(i?" ":"")<<a[i];
	return os<<']';
}

const int H=10,W=10;

inline bool change_cell(vvi& grid,int i,int j,int x)
{
	if(i<0 || H<=i || j<0 || W<=j) return true;
	if(grid[i][j]+x<0) return false;
	grid[i][j]+=x;
	return true;
}
inline bool change_large(vvi& grid,int ci,int cj,int x)
{
	if(ci<2 || H-2<=ci || cj<2 || W-2<=cj) return false;
	const int di[]={-2,-1,-1,-1,0,0,0,0,0,1,1,1,2};
	const int dj[]={0,-1,0,1,-2,-1,0,1,2,-1,0,1,0};
	rep(i,13) if(!change_cell(grid,ci+di[i],cj+dj[i],x)){
		rep(j,i) change_cell(grid,ci+di[j],cj+dj[j],-x);
		return false;
	}
	return true;
}
inline bool change_medium(vvi& grid,int ci,int cj,int x)
{
	if(ci<1 || H-1<=ci || cj<1 || W-1<=cj) return false;
	const int di[]={-1,-1,-1,0,0,0,1,1,1};
	const int dj[]={-1,0,1,-1,0,1,-1,0,1};
	rep(i,9) if(!change_cell(grid,ci+di[i],cj+dj[i],x)){
		rep(j,i) change_cell(grid,ci+di[j],cj+dj[j],-x);
		return false;
	}
	return true;
}
inline bool change_small(vvi& grid,int ci,int cj,int x)
{
	if(ci<1 || H-1<=ci || cj<1 || W-1<=cj) return false;
	const int di[]={-1,0,0,0,1};
	const int dj[]={0,-1,0,1,0};
	rep(i,5) if(!change_cell(grid,ci+di[i],cj+dj[i],x)){
		rep(j,i) change_cell(grid,ci+di[j],cj+dj[j],-x);
		return false;
	}
	return true;
}
// 拭き取る
inline bool wipe_large(vvi& grid,int ci,int cj)
{
	return change_large(grid,ci,cj,-1);
}
inline bool wipe_medium(vvi& grid,int ci,int cj)
{
	return change_medium(grid,ci,cj,-1);
}
inline bool wipe_small(vvi& grid,int ci,int cj)
{
	return change_small(grid,ci,cj,-1);
}
// 染める
inline bool dip_large(vvi& grid,int ci,int cj)
{
	return change_large(grid,ci,cj,1);
}
inline bool dip_medium(vvi& grid,int ci,int cj)
{
	return change_medium(grid,ci,cj,1);
}
inline bool dip_small(vvi& grid,int ci,int cj)
{
	return change_small(grid,ci,cj,1);
}

inline bool solve(vvi& grid,int cur,int rest,vector<pair<pii,int>>& dips)
{
	if(rest==0){
		rep(i,H) rep(j,W) if(grid[i][j]) return false;
		return true;
	}
	
	// 枝刈り
	rep(i,cur/W-2) rep(j,W) if(grid[i][j]) return false;
	
	repi(k,cur,H*W){
		int i=k/W,j=k%W;
		
		if(wipe_large(grid,i,j)){
			dips.emplace_back(mp(i,j),3);
			if(solve(grid,k,rest-1,dips))
				return true;
			dip_large(grid,i,j);
			dips.pop_back();
		}
		if(wipe_medium(grid,i,j)){
			dips.emplace_back(mp(i,j),2);
			if(solve(grid,k,rest-1,dips))
				return true;
			dip_medium(grid,i,j);
			dips.pop_back();
		}
		if(wipe_small(grid,i,j)){
			dips.emplace_back(mp(i,j),1);
			if(solve(grid,k,rest-1,dips))
				return true;
			dip_small(grid,i,j);
			dips.pop_back();
		}
	}
	return false;
}

int main()
{
	for(int n;cin>>n && n;){
		vvi grid(H,vi(W));
		rep(i,H) rep(j,W) cin>>grid[i][j];
		
		vector<pair<pii,int>> dips;
		assert(solve(grid,0,n,dips));
		
		for(auto d:dips)
			printf("%d %d %d\n",d.first.second,d.first.first,d.second);
	}
	
	return 0;
}