#include <bits/stdc++.h>
using namespace std;
class IMAGE {
public:
struct Pixel {
int r, g, b;
Pixel(int x = 0, int y = 0, int z = 0):
r(x), g(y), b(z) {}
void read() {
scanf("%d %d %d", &r, &g, &b);
}
Pixel operator-(const Pixel &x) const {
return Pixel(r-x.r, g-x.g, b-x.b);
}
Pixel operator+(const Pixel &x) const {
return Pixel(r+x.r, g+x.g, b+x.b);
}
Pixel operator*(const double x) const {
return Pixel(r*x, g*x, b*x);
}
Pixel operator/(const double x) const {
return Pixel(r/x, g/x, b/x);
}
void print() {
printf("%d %d %d", r, g, b);
}
int length() {
return abs(r) + abs(g) + abs(b);
}
double dist(Pixel x) {
return sqrt((r-x.r)*(r-x.r)+(g-x.g)*(g-x.g)+(b-x.b)*(b-x.b));
}
};
int W, H;
static const int MAXN = 256;
Pixel data[MAXN][MAXN*3], tmp[MAXN][MAXN*3];
int energy[MAXN][MAXN], dp[MAXN][MAXN];
long long seed;
int random() {
return seed = ( seed * 9301 + 49297 ) % 233280;
}
void getSquarePosition(int &x, int &y, int L) {
y = (W <= L) ? 0 : random() % (W - L);
x = (H <= L) ? 0 : random() % (H - L);
}
void read() {
scanf("%d %d", &W, &H);
for (int i = 0; i < H; i++)
for (int j = 0; j < W; j++)
data[i][j].read();
seed = 0;
}
int isValid(int x, int y) {
return x >= 0 && y >= 0 && x < H && y < W;
}
void pattern(int L, int N) {
int ERROR_TRY = 50;
int threshold = round(L*255/8.0);
int overlap = round(L/2.0);
int lx, ly, tW = 0, path[MAXN] = {};
for (int n = 0, it; n < N; n++) {
for (it = 0; it < ERROR_TRY; it++) {
getSquarePosition(lx, ly, L);
if (n == 0) {
for (int i = 0; i < L; i++)
for (int j = 0; j < L; j++)
tmp[i][j] = data[lx+i][ly+j];
tW = L;
break;
}
for (int i = 0; i < L; i++) {
for (int j = 0; j < overlap; j++) {
energy[i][j] = round(data[lx+i][ly+j].dist(tmp[i][tW-overlap+j]));
}
}
int cost = shrink(path, L, overlap);
if (cost < threshold) {
for (int i = 0; i < L; i++) {
for (int j = L-1; j >= path[i]; j--)
tmp[i][tW-overlap+j] = data[lx+i][ly+j];
}
tW += L - overlap;
break;
}
}
if (it == ERROR_TRY)
return ;
}
W = tW, H = L;
for (int i = 0; i < H; i++)
for (int j = 0; j < W; j++)
data[i][j] = tmp[i][j];
}
int shrink(int path[], int H, int W) {
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
int &val = dp[i][j];
if (i == 0) val = energy[i][j];
else {
val = dp[i-1][j];
if (j-1 >= 0)
val = min(val, dp[i-1][j-1]);
if (j+1 < W)
val = min(val, dp[i-1][j+1]);
val += energy[i][j];
}
}
}
int st = 0, cost;
for (int i = 0; i < W; i++)
if (dp[H-1][i] < dp[H-1][st])
st = i;
cost = dp[H-1][st];
for (int i = H-1; i >= 0; i--) {
path[i] = st;
if (i == 0) continue;
int val = dp[i][st] - energy[i][st];
if (st-1 >= 0 && val == dp[i-1][st-1])
st = st-1;
else if (val == dp[i-1][st])
st = st;
else
st = st+1;
}
return cost;
}
void print() {
printf("%d %d\n", W, H);
for (int i = 0; i < H; i++)
for (int j = 0; j < W; j++)
data[i][j].print(), printf("%c", j == W-1 ? '\n' : ' ');
}
} test;
int main() {
int n, L, N;
scanf("%d %d", &L, &N);
test.read();
test.pattern(L, N);
test.print();
return 0;
}