#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <cassert>
#include <sstream>
using namespace std;
#define REP(i,n) for(int i=0;i<(int)n;++i)
typedef pair<int,int> Point;
const int N = 10, M = 12;
int blur[N][N], COUNT, TOTAL, total;
enum Size{ LARGE, MID, SMALL, N_SIZE };
vector<Point> delta[] = { //dx,dy
    vector<Point> {
        Point(0,0), Point(-1,0), Point(0,-1), Point(1,0), Point(0,1),
        Point(-1,-1), Point(1,-1), Point(1,1), Point(-1,1),
        Point(-2,0), Point(0,-2), Point(2,0), Point(0,2)
    }, vector<Point> {
        Point(0,0), Point(-1,0), Point(0,-1), Point(1,0), Point(0,1),
        Point(-1,-1), Point(1,-1), Point(1,1), Point(-1,1)
    }, vector<Point>{
        Point(0,0), Point(-1,0), Point(0,-1), Point(1,0), Point(0,1)
    },
};
int minimul_count[]={13, 9, 5};
Point target[]{ Point(0,2), Point(1,1), Point(0,1) };
struct Data {
    int x, y, size;
    Data(){}
    Data(int x, int y, int size): x(x), y(y), size(size){}
    string description() const {
        ostringstream oss;
        oss << x << " " << y << " " << N_SIZE-size;
        return oss.str();
    }
};
Data history[M];
inline bool canSub(const Data &data){
    for(const Point &d: delta[data.size]){
        Data p(data.x+d.first, data.y+d.second, data.size);
        if(!(0 <= p.x && p.y < N && 0 <= p.x && p.x < N && blur[p.y][p.x] != 0)) return false;
    }
    return true;
}
inline void add(const Data &d){
    for(const Point &p: delta[d.size]){ ++blur[d.y+p.second][d.x+p.first]; ++total;}
}
inline void sub(const Data &d){
    for(const Point &p: delta[d.size]){ --blur[d.y+p.second][d.x+p.first]; --total;}
}
bool solve(const Data &b, int d){
    if(d == COUNT && total == 0) return true;
    Point p(-1,-1);
    [&](){ REP(y,N) REP(x,N) if(blur[y][x] > 0){ p.first = x; p.second = y; return; } }();
    if(p.first < N-1 && p.second < N-1 && p.first != -1){
        REP(size,N_SIZE){
            if(minimul_count[size] > total) continue;
            Data data = Data(p.first + target[size].first, p.second + target[size].second, size);
            if(canSub(data)){
                sub(data);
                history[d] = data;
                if(solve(data, d+1)) return true;
            }
        }
    }
    add(b);
    return false;
}
int main(){
    cin >> COUNT;
    REP(i,N) REP(j,N){ cin >> blur[i][j]; TOTAL += blur[i][j]; }
    total = TOTAL;
    assert(solve(Data(),0));
    REP(i,COUNT) cout << history[i].description() << endl;
}