def parse(inFile):
return [inFile.getInts() for k in xrange(inFile.getInts()[0])]
def solve(grid):
[w,h] = [len(grid[0]),len(grid)]
dest = [[(i,j) for j in xrange(w)] for i in xrange(h)]
for i in xrange(h):
for j in xrange(w):
if (i > 0) and grid[i-1][j] < grid[dest[i][j][0]][dest[i][j][1]]:
dest[i][j] = (i - 1, j)
if (j > 0) and grid[i][j-1] < grid[dest[i][j][0]][dest[i][j][1]]:
dest[i][j] = (i, j - 1)
if (j + 1 < w) and grid[i][j+1] < grid[dest[i][j][0]][dest[i][j][1]]:
dest[i][j] = (i, j + 1)
if (i + 1 < h) and grid[i+1][j] < grid[dest[i][j][0]][dest[i][j][1]]:
dest[i][j] = (i + 1, j)
for k in xrange(14):
for i in xrange(h):
for j in xrange(w):
(i0,j0) = dest[i][j]
dest[i][j] = dest[i0][j0]
grid = [["" for g in row] for row in grid]
labels = {}
nextLabel = "a"
for i in xrange(h):
for j in xrange(w):
if labels.has_key(dest[i][j]):
grid[i][j] = labels[dest[i][j]]
else:
labels[dest[i][j]] = nextLabel
grid[i][j] = nextLabel
nextLabel = chr(ord(nextLabel) + 1)
return "\n".join([""]+[" ".join(row) for row in grid])
if __name__ == "__main__":
from GCJ import GCJ
GCJ(parse, solve, "/Users/lpebody/gcj/2009_q/", "b").run()
ZGVmIHBhcnNlKGluRmlsZSk6CiAgICByZXR1cm4gW2luRmlsZS5nZXRJbnRzKCkgZm9yIGsgaW4geHJhbmdlKGluRmlsZS5nZXRJbnRzKClbMF0pXQoKZGVmIHNvbHZlKGdyaWQpOgogICAgW3csaF0gPSBbbGVuKGdyaWRbMF0pLGxlbihncmlkKV0KICAgIGRlc3QgPSBbWyhpLGopIGZvciBqIGluIHhyYW5nZSh3KV0gZm9yIGkgaW4geHJhbmdlKGgpXQogICAgZm9yIGkgaW4geHJhbmdlKGgpOgogICAgICAgIGZvciBqIGluIHhyYW5nZSh3KToKICAgICAgICAgICAgaWYgKGkgPiAwKSBhbmQgZ3JpZFtpLTFdW2pdIDwgZ3JpZFtkZXN0W2ldW2pdWzBdXVtkZXN0W2ldW2pdWzFdXToKICAgICAgICAgICAgICAgIGRlc3RbaV1bal0gPSAoaSAtIDEsIGopCiAgICAgICAgICAgIGlmIChqID4gMCkgYW5kIGdyaWRbaV1bai0xXSA8IGdyaWRbZGVzdFtpXVtqXVswXV1bZGVzdFtpXVtqXVsxXV06CiAgICAgICAgICAgICAgICBkZXN0W2ldW2pdID0gKGksIGogLSAxKQogICAgICAgICAgICBpZiAoaiArIDEgPCB3KSBhbmQgZ3JpZFtpXVtqKzFdIDwgZ3JpZFtkZXN0W2ldW2pdWzBdXVtkZXN0W2ldW2pdWzFdXToKICAgICAgICAgICAgICAgIGRlc3RbaV1bal0gPSAoaSwgaiArIDEpCiAgICAgICAgICAgIGlmIChpICsgMSA8IGgpIGFuZCBncmlkW2krMV1bal0gPCBncmlkW2Rlc3RbaV1bal1bMF1dW2Rlc3RbaV1bal1bMV1dOgogICAgICAgICAgICAgICAgZGVzdFtpXVtqXSA9IChpICsgMSwgaikKICAgIGZvciBrIGluIHhyYW5nZSgxNCk6CiAgICAgICAgZm9yIGkgaW4geHJhbmdlKGgpOgogICAgICAgICAgICBmb3IgaiBpbiB4cmFuZ2Uodyk6CiAgICAgICAgICAgICAgICAoaTAsajApID0gZGVzdFtpXVtqXQogICAgICAgICAgICAgICAgZGVzdFtpXVtqXSA9IGRlc3RbaTBdW2owXQogICAgZ3JpZCA9IFtbIiIgZm9yIGcgaW4gcm93XSBmb3Igcm93IGluIGdyaWRdCiAgICBsYWJlbHMgPSB7fQogICAgbmV4dExhYmVsID0gImEiCiAgICBmb3IgaSBpbiB4cmFuZ2UoaCk6CiAgICAgICAgZm9yIGogaW4geHJhbmdlKHcpOgogICAgICAgICAgICBpZiBsYWJlbHMuaGFzX2tleShkZXN0W2ldW2pdKToKICAgICAgICAgICAgICAgIGdyaWRbaV1bal0gPSBsYWJlbHNbZGVzdFtpXVtqXV0KICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGxhYmVsc1tkZXN0W2ldW2pdXSA9IG5leHRMYWJlbAogICAgICAgICAgICAgICAgZ3JpZFtpXVtqXSA9IG5leHRMYWJlbAogICAgICAgICAgICAgICAgbmV4dExhYmVsID0gY2hyKG9yZChuZXh0TGFiZWwpICsgMSkKICAgIHJldHVybiAiXG4iLmpvaW4oWyIiXStbIiAiLmpvaW4ocm93KSBmb3Igcm93IGluIGdyaWRdKQoKaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKICAgIGZyb20gR0NKIGltcG9ydCBHQ0oKICAgIEdDSihwYXJzZSwgc29sdmUsICIvVXNlcnMvbHBlYm9keS9nY2ovMjAwOV9xLyIsICJiIikucnVuKCkK