#include #define FOR(i, n) for(int i = 0; i < (n); ++i) #define REP(i, a, b) for(int i = (a); i < (b); ++i) #define TRAV(i, a) for(auto &i : (a)) #define SZ(x) ((int)(x).size()) #define X first #define Y second #define PR std::pair #define MP std::make_pair typedef long long ll; typedef std::vector VI; typedef std::pair PII; char tab[105][105]; int kto[105][105]; std::vector> mms; std::vector> moje; int fre = 0; int n, m; PII operator+(PII a, PII b){ return MP(a.X+b.X, a.Y+b.Y); } PII operator-(PII a, PII b){ return MP(a.X-b.X, a.Y-b.Y); } std::vector DIRS{{1, 0}, {0, 1}, {0, -1}, {-1, 0}}; bool bounds(PII a){ return a.X >= 0 && a.Y >= 0 && a.X < n && a.Y < m; } void ustaw(PII& val, int co){ if(val.X == -1 || (val.X != -1 && val.X > co)) val.X = co; if(val.Y == -1 || (val.Y != -1 && val.Y < co)) val.Y = co; } void spojne(){ auto jazda = [&](PII pos, int ind, std::vector& vec, std::vector& my){ vec = std::vector(n, MP(-1, -1)); std::queue que; que.push(pos); kto[pos.X][pos.Y] = ind; ustaw(vec[pos.X], pos.Y); while(SZ(que)){ auto v = que.front(); que.pop(); my.push_back(v); TRAV(d, DIRS){ auto p = v + d; if(!bounds(p) || kto[p.X][p.Y] != -1 || tab[p.X][p.Y] != tab[v.X][v.Y]) continue; que.push(p); kto[p.X][p.Y] = ind; ustaw(vec[p.X], p.Y); } } }; FOR(i, n) FOR(j, m) kto[i][j] = -1; FOR(i, n){ FOR(j, m){ if(kto[i][j] == -1){ mms.emplace_back(); moje.emplace_back(); jazda(MP(i, j), fre++, mms.back(), moje.back()); } } } } std::string encode(){ spojne(); std::vector done(fre); std::string ret; FOR(i, n){ FOR(j, m){ if(done[kto[i][j]]) continue; done[kto[i][j]] = true; auto& mm = mms[kto[i][j]]; std::set set; TRAV(pr, moje[kto[i][j]]){ TRAV(d, DIRS){ auto p = pr + d; if(!bounds(p) || mm[p.X].X == -1 || kto[p.X][p.Y] == kto[i][j]) continue; if(mm[p.X].X < p.Y && mm[p.X].Y > p.Y){ set.insert(kto[p.X][p.Y]); } } } if(SZ(set)) ret.push_back((char)('a' + SZ(set) - 1)); } } return ret; } char out[3005][3005]; char chr(int co){ if(co) return '.'; return '#'; } void decode(std::string s){ std::function rec = [&](PII tl, PII sz, int pos, int co){ assert(sz.X >= 0 && sz.Y >= 0); // TODO: more strict? if(pos == SZ(s)){ FOR(i, sz.X) FOR(j, sz.Y) out[tl.X+i][tl.Y+j] = chr(co); return; } int ile = s[pos] - 'a'; if(ile == 0){ FOR(i, sz.X) out[tl.X+i][tl.Y] = out[tl.X+i][tl.Y+sz.Y-1] = chr(co); FOR(j, sz.Y) out[tl.X][tl.Y+j] = out[tl.X+sz.X-1][tl.Y+j] = chr(co); rec(tl + MP(1, 1), sz - MP(2, 2), pos+1, 1-co); }else{ assert(sz.Y >= ile); // TODO: kejsy FOR(i, sz.X) out[tl.X+i][tl.Y] = out[tl.X+i][tl.Y+sz.Y-1] = chr(co); FOR(j, sz.Y) out[tl.X][tl.Y+j] = out[tl.X+sz.X-1][tl.Y+j] = chr(co); FOR(xd, 3) FOR(j, sz.Y) out[tl.X+xd][tl.Y+j] = chr(co); FOR(hehe, ile){ out[tl.X+1][tl.Y+1+2*hehe] = chr(1-co); } rec(tl + MP(3, 1), sz - MP(4, 2), pos+1, 1-co); } }; int SSS = 3000; std::cout << SSS << " " << SSS << "\n"; FOR(i, SSS) FOR(j, SSS) out[i][j] = ' '; rec(MP(0, 0), MP(SSS, SSS), 0, 0); FOR(i, SSS){ FOR(j, SSS){ std::cout << out[i][j]; } std::cout << "\n"; } } int main(){ std::ios_base::sync_with_stdio(false); std::cin.tie(0); std::cin >> n >> m; FOR(i, n) FOR(j, m) std::cin >> tab[i][j]; auto s = encode(); assert(SZ(s)); std::reverse(s.begin(), s.end()); decode(s); return 0; }