#include <bits/stdc++.h>
using namespace std;

const int dx[] = {0,  -1, 0, 1, 0,  -1, 1, 1, -1,  -2, 0, 2, 0};
const int dy[] = {0,  0, -1, 0, 1,  -1, -1, 1, 1,  0, -2, 0, 2};
const int sz[] = {5, 9, 13};

struct Ink {
	int x, y, val;
	Ink(int x = 0, int y = 0, int val = 0) : x(x), y(y), val(val) {}
	bool operator < (const Ink &t) const {
		if (x != t.x) return x < t.x;
		if (y != t.y) return y < t.y;
		return val < t.val;
	}
};

set<int> done;
int grid[10][10];

inline int hash_(vector<Ink> &c, int n, int nx, int ny)
{
	typedef unsigned int uint;
	uint p = 1e9 + 7;
	uint mod = 1e9 + 9;
	uint h = 0;
	for (int i = 0; i < c.size(); i++){
		h = (h * p + c[i].x) % mod;
		h = (h * p + c[i].y) % mod;
		h = (h * p + c[i].val) % mod;
	}
	h = (h * p + n) % mod;
	h = (h * p + nx) % mod;
	h = (h * p + ny) % mod;
	return h;
}

inline bool ingrid(int x, int y)
{
	return x >= 0 && y >= 0 && x < 10 && y < 10;
}

vector<Ink> search(int n, vector<Ink> c, int nx, int ny)
{
	if (n == 0){
		if (c.size() == 0) return vector<Ink>(1);
		else return vector<Ink>(0);
	}
	if (c.size() == 0) return vector<Ink>(0);
	
	
	for (int i = 0; i < c.size(); i++){
		if (nx - 2 > c[i].x) return vector<Ink>(0);
		else if (nx - 2 == c[i].x){
			if (ny > c[i].y) return vector<Ink>(0);
		}
	}
	
	
	memset(grid, 0, sizeof(grid));
	for (int i = 0; i < c.size(); i++){
		grid[c[i].x][c[i].y] = c[i].val;
	}
	
	for (; nx < 10; nx++){
		for (; ny < 10; ny++){
			for (int s = 0; s < 3; s++){
				bool f = true;
				for (int dir = 0; dir < sz[s]; dir++){
					int tx = nx + dx[dir];
					int ty = ny + dy[dir];
					//if (!ingrid(tx, ty)) continue;
					if (!ingrid(tx, ty) || grid[tx][ty] == 0){
						for (int dir2 = 0; dir2 < dir; dir2++){
							int tx2 = nx + dx[dir2];
							int ty2 = ny + dy[dir2];
							grid[tx2][ty2]++;
						}
						f = false;
						break;
					}
					grid[tx][ty]--;
				}
				if (!f) continue;
				vector<Ink> v;
				for (int i = 0; i < c.size(); i++){
					if (grid[c[i].x][c[i].y]){
						v.push_back(Ink(c[i].x, c[i].y, grid[c[i].x][c[i].y]));
					}
				}
				vector<Ink> t = search(n - 1, v, nx, ny);
				if (t.size()){
					t.push_back(Ink(nx, ny, s));
					return t;
				}
				for (int dir = 0; dir < sz[s]; dir++){
					int tx = nx + dx[dir];
					int ty = ny + dy[dir];
					//if (!ingrid(tx, ty)) continue;
					grid[tx][ty]++;
				}
			}
		}
		ny = 0;
	}
	
	int h = hash_(c, n, nx, ny);
	if (done.count(h)) return vector<Ink>(0);
	done.insert(h);
	
	return vector<Ink>(0);
}

int main()
{
	int n;
	scanf("%d", &n);
	vector<Ink> c;
	for (int i = 0; i < 10; i++){
		for (int j = 0; j < 10; j++){
			int x;
			scanf("%d", &x);
			if (x) c.push_back(Ink(i, j, x));
		}
	}
	
	vector<Ink> res = search(n, c, 0, 0);
	for (int i = 1; i < res.size(); i++){
		printf("%d %d %d\n", res[i].y, res[i].x, ++res[i].val);
	}
}