#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

struct drop{
  int x, y, t;
  drop(int _x, int _y, int _t) : x(_x), y(_y), t(_t) {}
  
  int real_x() const {
    return t==2 ? x+1 : x;
  }
  int real_y() const {
    return t==3 ? y+2 : y+1;
  }
};

ostream& operator<<(ostream& os, const drop& d) {
  os << d.real_x() << " " << d.real_y() << " " << d.t;
  return os;
}

struct field{
  int f[10][10];
  int remain;
  
  void calc_remain() {
    remain = 0;
    for(int y=0; y<10; y++) for(int x=0; x<10; x++) remain += f[y][x];
  }
  
  bool can_put(int x, int y, int t) {
    switch(t) {
      case 3:
        if(x<2 || x>=8 || y>=6) return false;
        return f[y][x]>0 && f[y+1][x-1]>0 && f[y+1][x]>0 && f[y+1][x+1]>0
                && f[y+2][x-2]>0 && f[y+2][x-1]>0 && f[y+2][x]>0 && f[y+2][x+1]>0 && f[y+2][x+2]>0
                && f[y+3][x-1]>0 && f[y+3][x]>0 && f[y+3][x+1]>0 && f[y+4][x]>0;
      case 2:
        if(x>=8 || y>=8) return false;
        return f[y][x]>0 && f[y][x+1]>0 && f[y][x+2]>0
                && f[y+1][x]>0 && f[y+1][x+1]>0 && f[y+1][x+2]>0
                && f[y+2][x]>0 && f[y+2][x+1]>0 && f[y+2][x+2]>0;
      case 1:
        if(x<1 || x>=9 || y>=8) return false;
        return f[y][x]>0 && f[y+1][x-1]>0 && f[y+1][x]>0 && f[y+1][x+1]>0 && f[y+2][x]>0;
    }
    return false;
  }
  
  void put(int x, int y, int t, int amount) {
    switch(t) {
      case 3:
        f[y][x] += amount;
        f[y+1][x-1] += amount;
        f[y+1][x] += amount;
        f[y+1][x+1] += amount;
        f[y+2][x-2] += amount;
        f[y+2][x-1] += amount;
        f[y+2][x] += amount;
        f[y+2][x+1] += amount;
        f[y+2][x+2] += amount;
        f[y+3][x-1] += amount;
        f[y+3][x] += amount;
        f[y+3][x+1] += amount;
        f[y+4][x] += amount;
        remain += 13 * amount;
        break;
      case 2:
        for(int i=0; i<=2; i++) for(int j=0; j<=2; j++)
          f[y+i][x+j] += amount;
        remain += 9 * amount;
        break;
      case 1:
        f[y][x] += amount;
        f[y+1][x-1] += amount;
        f[y+1][x] += amount;
        f[y+1][x+1] += amount;
        f[y+2][x] += amount;
        remain += 5 * amount;
        break;
    }
  }
};

bool search(field& f, vector<drop>& ds, int n, int y=0, int x=0, int t=3) {
  //cerr << "search " << n << ": (" << x << ", " << y << "; " << t << ")" << endl;
  if(n==0) return f.remain == 0;
  if(y>=10) return false;
  if(x>=10) return search(f, ds, n, y+1, 0, 3);
  if(f.f[y][x]==0) return search(f, ds, n, y, x+1, 3);
  if(t==0) return false;
  if(f.can_put(x, y, t)) {
    //cerr << "put " << n << ": (" << x << ", " << y << "; " << t << ")" << endl;
    ds.push_back(drop(x, y, t));
    f.put(x, y, t, -1);
    bool res = search(f, ds, n-1, y, x, t);
    if(res) return true;
    //cerr << "remove " << n << ": (" << x << ", " << y << "; " << t << ")" << endl;
    f.put(x, y, t, 1);
    ds.pop_back();
  }
  return search(f, ds, n, y, x, t-1);
}

int main(){
  int n;
  cin >> n;
  field f;
  for(int y=0; y<10; y++) for(int x=0; x<10; x++) {
    cin >> f.f[y][x];
  }
  f.calc_remain();
  vector<drop> ds;
  search(f, ds, n);
  for(drop& d : ds) {
    cout << d << endl;
  }
}



Measured memory_bytes: 3112