#include using namespace std; typedef long long ll; const int N = 1000 + 3; #define all(x) (x).begin(), (x).end() //https://gist.github.com/Chillee/ad2110fc17af453fb6fc3357a78cfd28#file-hlpp-cpp template struct Dinic { const static bool SCALING = true; // non-scaling = V^2E, Scaling=VElog(U) with higher constant int lim = 1; const T INF = numeric_limits::max(); struct edge { int to, rev; T cap, flow; }; int s = MAXV - 2, t = MAXV - 1; int level[MAXV], ptr[MAXV]; vector adj[MAXV]; void addEdge(int a, int b, T cap, bool isDirected = true) { adj[a].push_back({b, (int)adj[b].size(), cap, 0}); adj[b].push_back({a, (int)adj[a].size() - 1, isDirected ? 0 : cap, 0}); } bool bfs() { queue q({s}); fill(level, level + MAXV, -1); level[s] = 0; while (!q.empty() && level[t] == -1) { int v = q.front(); q.pop(); for (auto e : adj[v]) { if (level[e.to] == -1 && e.flow < e.cap && (!SCALING || e.cap - e.flow >= lim)) { q.push(e.to); level[e.to] = level[v] + 1; } } } return level[t] != -1; } T dfs(int v, T flow) { if (v == t || !flow) return flow; for (; ptr[v] < adj[v].size(); ptr[v]++) { edge &e = adj[v][ptr[v]]; if (level[e.to] != level[v] + 1) continue; if (T pushed = dfs(e.to, min(flow, e.cap - e.flow))) { e.flow += pushed; adj[e.to][e.rev].flow -= pushed; return pushed; } } return 0; } long long calc() { long long flow = 0; for (lim = SCALING ? (1 << 30) : 1; lim > 0; lim >>= 1) { while (bfs()) { fill(ptr, ptr + MAXV, 0); while (T pushed = dfs(s, INF)) flow += pushed; } } return flow; } }; int n, m, row_g[N], col_g[N], row_f[N], col_f[N]; string s[N]; Dinic<2 * N> d; void input(string s){ freopen((s + ".in").c_str(), "r", stdin); freopen((s + ".out").c_str(), "w", stdout); } int main(){ ios::sync_with_stdio(false); cin.tie(NULL); input("blueandgreen"); cin >> n >> m; for(int i = 0; i < n; ++i) cin >> s[i]; for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j){ if(s[i][j] == 'g'){ ++row_g[i]; ++col_g[j]; } else if(s[i][j] == '_'){ ++row_f[i]; ++col_f[j]; } } d.s = 0; d.t = n + m + 1; //{0} //[1, n] //[n + 1, n + m] //{n + m + 1} for(int i = 0; i < n; ++i){ if(row_f[i] + row_g[i] < m / 2 || m - row_g[i] < m / 2){ cout << "-1\n"; return 0; } d.addEdge(0, i + 1, m / 2 - row_g[i]); } int expected = 0; for(int i = 0; i < m; ++i){ if(col_f[i] + col_g[i] < n / 2 || n - col_g[i] < n / 2){ cout << "-1\n"; return 0; } expected += n / 2 - col_g[i]; d.addEdge(i + n + 1, n + m + 1, n / 2 - col_g[i]); } for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j) if(s[i][j] == '_') d.addEdge(i + 1, j + n + 1, 1); if(d.calc() != expected){ cout << "-1\n"; return 0; } for(int i = 1; i <= n; ++i) for(auto e: d.adj[i]){ if(!e.to) continue; if(e.flow == 1) s[i - 1][e.to - n - 1] = 'g'; else s[i - 1][e.to - n - 1] = 'b'; } for(int i = 0; i < n; ++i) cout << s[i] << "\n"; }