Problem:
塗りつぶしゲーム
指で画面にタッチして操作することのできるタブレットインターフェースの技術は、ゲームの分野でも応用され、新しい操作感を持つ様々な種類のゲームが作られています。現在、ＡＺ社が開発しているゲームもその一つです。
このソフトウェア（ゲーム）の要件は以下の通りです。
画面には
X
列×
Y
行の2次元グリッドがあります。
グリッドのセルは赤(R)、緑(G)、茶(B)の3色のいずれかで塗られています。
セルの色を変更するボタンR、G、Bがあり、このボタンが押下されると一番左上(0,0)のセルがその色に変更されます。
一番左上のセルの色が変更されると、そのセルの元の色と同じ色に塗られた隣接するすべてのセルが指定された色に変わります。すなわち、元の色が同じ色のセルでつながったセルはすべて指定された色に変更されます。
このようにグリッドを塗りつぶしていき、最終的にグリッド全体を一色にするというゲームです。少ない手順で解くと高得点が与えられます。
ＡＺ社のプログラマーであるあなたは、このゲームのロジックの一部分を開発することになりました。まずは、この最高得点を計算するため、このゲームを最短で解いた場合、最低何回選択ボタンを操作すればグリッドが一色になるかをもとめるプログラムを作ることにしました。
入力
複数のデータセットが与えられます。入力の終わりはゼロふたつで示されます。各データセットは以下の形式で与えられます。
X
Y
c
1,1
c
2,1
...
c
X,1
c
1,2
c
2,2
...
c
X,2
:
c
1,Y
c
2,Y
...
c
X,Y
1行目にグリッドの列と行のサイズ
X
,
Y
(2 ≤
X
,
Y
≤ 10) が与えられます。続く
Y
行に
i
列目
j
行目のセルの色を表す文字
c
i,j
が空白区切りで与えられます。
出力
データセットごとに、ボタン操作の最少回数を1行に出力します。
入力例
3 3
R G B
G G G
G B B
2 4
R G
G G
R B
B R
4 3
G G B R
G R R G
B G G R
0 0
出力例
2
4
4

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;

int x,y;

struct S{
  int t;
  vector<char> g;
};

void fill(vector<char> &g,int xx,int yy,char c,char sc){
  if(xx<0||x<=xx||yy<0||y<=yy||sc!=g[yy*x+xx])return;
  g[yy*x+xx]=c;
  for(int i=0;i<4;i++){
    int d[]={0,1,0,-1,0};
    fill(g,xx+d[i],yy+d[i+1],c,sc);
  }
}

int main(){
  while(cin>>x>>y,x|y){
    vector<char> g(y*x);
    for(int i=0;i<y*x;i++){
      cin>>g[i];
    }
    queue<S> que;
    S is={0,g};
    que.push(is);
    for(;;){
      S cs=que.front();
      char l='Z',h='A';
      for(int i=0;i<y*x;i++){
        l=min(l,cs.g[i]);
        h=max(h,cs.g[i]);
      }
      if(l==h)break;
      que.pop();
      for(int i=0;i<3;i++){
        const char *c="RGB";
        if(c[i]==cs.g[0])continue;
        S ns={cs.t+1,cs.g};
        fill(ns.g,0,0,c[i],ns.g[0]);
        que.push(ns);
      }

    }
      
    cout<<que.front().t<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 980
memory_kb: 37192
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;

int x,y;

struct S{
  int t;
  vector<char> g;
};

void fill(vector<char> &g,int xx,int yy,char c,char sc){
  if(xx<0||x<=xx||yy<0||y<=yy||sc!=g[yy*x+xx])return;
  g[yy*x+xx]=c;
  for(int i=0;i<4;i++){
    int d[]={0,1,0,-1,0};
    fill(g,xx+d[i],yy+d[i+1],c,sc);
  }
}

int main(){
  while(cin>>x>>y,x|y){
    vector<char> g(y*x);
    for(int i=0;i<y*x;i++){
      cin>>g[i];
    }
    queue<S> que;
    S is={0,g};
    que.push(is);
    for(;;){
      S cs=que.front();
      char l='Z',h='A';
      for(int i=0;i<y*x;i++){
	      l=min(l,cs.g[i]);
	      h=max(h,cs.g[i]);
      }
      if(l==h)break;
      que.pop();
      for(int i=0;i<3;i++){
	const char *c="RGB";
	if(c[i]==cs.g[0])continue;
	S ns={cs.t+1,cs.g};
	fill(ns.g,0,0,c[i],ns.g[0]);
	que.push(ns);
      }
    }
    cout<<que.front().t<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 980
memory_kb: 37220
final_rank: 14

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <vector>
#include <deque>
#include <set>
using namespace std;

typedef pair<int, int> Pii;


bool is_finished(int w, int h, const vector<vector<int>>& grid) {
	for (int y = 0; y < h; y++) {
		for (int x = 0; x < w; x++) {
			if (grid[y][x] != grid[0][0]) {
				return false;
			}
		}
	}
	return true;
}

vector<Pii> get_same_color_xy_list(int w, int h, const vector<vector<int>>& grid) {
	vector<Pii> same_color_xy_list(1, {0, 0});
	vector<Pii> stack(1, { 0, 0 });
	set<Pii> is_visited;
	int c = grid[0][0];
	Pii dx_dy_list[] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1} };

	is_visited.insert({ 0, 0 });
	while (!stack.empty()) {
		const Pii e = stack.back(); stack.pop_back();
		int cx = e.first;
		int cy = e.second;
		
		for (const Pii& dx_dy : dx_dy_list) {
			int nx = cx + dx_dy.first;
			int ny = cy + dx_dy.second;

			if (nx < 0 || nx >= w || ny < 0 || ny >= h || grid[ny][nx] != c || is_visited.count({ nx, ny }) > 0) {
				continue;
			}

			is_visited.insert({ nx, ny });
			same_color_xy_list.push_back({ nx, ny });
			stack.push_back({ nx, ny });
		}
	}
	return same_color_xy_list;
}

bool dls(int w, int h, int max_d, int cd, vector<vector<int>>& grid) {
	if (cd >= max_d) {
		return false;
	}

	int nd = cd + 1;
	vector<Pii> same_color_xy_list = get_same_color_xy_list(w, h, grid);
	int org_c = grid[0][0];

	for (int c = 0; c < 3; c++) {
		if (c == org_c) {
			continue;
		}

		for (const Pii& xy : same_color_xy_list) {
			grid[xy.second][xy.first] = c;
		}
		
		if (is_finished(w, h, grid)) {
			return true;
		}

		if (dls(w, h, max_d, nd, grid)) {
			return true;
		}

		for (const Pii& xy : same_color_xy_list) {
			grid[xy.second][xy.first] = org_c;
		}
	}
	return false;
}

int main() {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		int w = 0;
		int h = 0;

		cin >> w >> h;
		if (w == 0 && h == 0) {
			break;
		}

		vector<vector<int>> grid(h, vector<int>(w, 0));
		for (int y = 0; y < h; y++) {
			for (int x = 0; x < w; x++) {
				char c = 0;

				cin >> c;
				if (c == 'R') {
					grid[y][x] = 0;
				}
				else if (c == 'G') {
					grid[y][x] = 1;
				}
				else {
					grid[y][x] = 2;
				}
			}
		}

		if (is_finished(w, h, grid)) {
			cout << 0 << endl;
			continue;
		}
		
		for (int i = 1; i < w * h; i++) {
			if (dls(w, h, i, 0, grid)) {
				cout << i << endl;
				break;
			}

		}
	}

	return 0;
}
accuracy: 1
time_ms: 2410
memory_kb: 3372
final_rank: 16

code_snippet: #define _USE_MATH_DEFINES
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<list>
#include<algorithm>
#include<numeric>
#include<cmath>
#include<climits>
#include<iomanip>
#include<cctype>
#include<sstream>
#include<regex>
#include<bitset>
#include<random>
#include<complex>
using namespace std;
#define int long long
#define uint unsigned long long
const int mod=1e9+7;
const int Mod=998244353;
const int inf=mod*mod;
const double eps=1e-9;
int dx[]={1,0,0,-1},dy[]={0,1,-1,0};
struct board{
	int x,y;
	char val[10][10];
	bool operator<(const board&b)const{
		for(int i=0;i<y;i++)
			for(int j=0;j<x;j++)
				if(val[i][j]!=b.val[i][j])
					return val[i][j]<b.val[i][j];
		return 0;
	}
	bool end(){
		for(int i=0;i<y;i++)
			for(int j=0;j<x;j++)
				if(val[i][j]!=val[0][0])
					return 0;
		return 1;
	}
	vector<board>next(){
		vector<board>ans;
		for(int i=0;i<3;i++){
			if(val[0][0]=="RGB"[i])
				continue;
			board tmp=*this;
			bool used[10][10]={};
			queue<pair<int,int>>que;
			used[0][0]=1;
			que.push({0,0});
			while(!que.empty()){
				int py=que.front().first,px=que.front().second;
				que.pop();
				tmp.val[py][px]="RGB"[i];
				for(int j=0;j<4;j++){
					int ny=py+dy[j],nx=px+dx[j];
					if(0<=ny&&ny<y&&0<=nx&&nx<x&&!used[ny][nx]&&val[0][0]==val[ny][nx]){
						used[ny][nx]=1;
						que.push({ny,nx});
					}
				}
			}
			ans.push_back(tmp);
		}
		return ans;
	}
};
signed main(){
	board puzzle;
	while(cin>>puzzle.x>>puzzle.y,puzzle.x){
		for(int i=0;i<puzzle.y;i++)
			for(int j=0;j<puzzle.x;j++)
				cin>>puzzle.val[i][j];
		map<board,int>dist;
		queue<board>que;
		dist[puzzle]=0;
		que.push(puzzle);
		while(!que.empty()){
			puzzle=que.front();
			que.pop();
			if(puzzle.end()){
				cout<<dist[puzzle]<<endl;
				break;
			}
			auto nxt=puzzle.next();
			for(auto&x:nxt){
				if(dist.count(x))
					continue;
				dist[x]=dist[puzzle]+1;
				que.push(x);
			}
		}
	}
}
accuracy: 1
time_ms: 30
memory_kb: 4472
final_rank: 1

code_snippet: #include<iostream>
#include<array>
#include<queue>
using namespace std;
using T=array<array<bool,10>,10>;
int ans;
int X,Y;
char c[10][10];
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
void dfs(int cnt,T now,char col)
{
	if(ans<=cnt)return;
	queue<pair<int,int> >P;
	for(int i=0;i<X;i++)for(int j=0;j<Y;j++)if(now[i][j])P.push(make_pair(i,j));
	int ok=0;
	bool R=false,G=false,B=false;
	while(!P.empty())
	{
		int x=P.front().first,y=P.front().second;
		P.pop();
		ok++;
		for(int r=0;r<4;r++)
		{
			int tx=x+dx[r],ty=y+dy[r];
			if(tx<0||ty<0||tx>=X||ty>=Y||now[tx][ty])continue;
			if(col==c[tx][ty])
			{
				now[tx][ty]=true;
				P.push(make_pair(tx,ty));
			}
			else if(c[tx][ty]=='R')R=true;
			else if(c[tx][ty]=='G')G=true;
			else if(c[tx][ty]=='B')B=true;
		}
	}
	if(ok==X*Y)
	{
		ans=cnt;
		return;
	}
	if(R)dfs(cnt+1,now,'R');
	if(G)dfs(cnt+1,now,'G');
	if(B)dfs(cnt+1,now,'B');
}
main()
{
	while(cin>>Y>>X,X)
	{
		T now;
		for(int i=0;i<X;i++)for(int j=0;j<Y;j++)
		{
			cin>>c[i][j];
			now[i][j]=false;
		}
		now[0][0]=true;
		ans=300;
		dfs(0,now,c[0][0]);
		cout<<ans<<endl;
	}
}
accuracy: 1
time_ms: 210
memory_kb: 3132
final_rank: 2

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int ans = 18; // worst case
int fill(int y, int x, int from, int to, vector<vector<int>> &panel){
    if(panel[y][x] != from) return 0;
    panel[y][x] = to;
    int res = 1;
    for(int d=0; d<4; d++){
        res += fill(y+dy[d], x+dx[d], from, to, panel);
    }
    return res;
}
int nextcolor(int y, int x, int from, vector<vector<bool>> &used, vector<bool> &nc, vector<vector<int>> &panel){
    if(used[y][x]) return 0;
    used[y][x] = true;
    if(panel[y][x] != from){
        if(panel[y][x]!=-1) nc[panel[y][x]] = true;
        return 0;
    }
    int res = 1;
    for(int d=0; d<4; d++){
        res += nextcolor(y+dy[d], x+dx[d], from, used, nc, panel);
    }
    return res;
}
void solve(int step, vector<vector<int>> &panel){
    if(step >= ans) return;
    int h = (int)panel.size() -2;
    int w = (int)panel[0].size() -2;
    vector<bool> next(3, false);
    vector<vector<bool>> used(h+2, vector<bool>(w+2, false));
    int ret = nextcolor(1, 1, panel[1][1], used, next, panel);
    if(ret == h*w){
        ans = step;
        return;
    }
    for(int i=0; i<3; i++){
        if(i == panel[1][1]) continue;
        if(!next[i]) continue;
        auto tmp = panel;
        fill(1, 1, panel[1][1], i, tmp);
        solve(step+1, tmp);
    }
}

int main(){
    while(1){
        int w,h;
        cin >> w >> h;
        if(h == 0) break;

        ans = 18;
        vector<vector<int>> panel(h+2, vector<int>(w+2, -1));
        for(int i=1; i<=h; i++){
            for(int j=1; j<=w; j++){
                char c;
                cin >> c;
                if(c == 'R') panel[i][j] = 0;
                if(c == 'G') panel[i][j] = 1;
                if(c == 'B') panel[i][j] = 2;
            }
        }
        solve(0, panel);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 620
memory_kb: 3216
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int ans = 19;
int fill(int y, int x, int from, int to, vector<vector<int>> &panel){
    if(panel[y][x] != from) return 0;
    panel[y][x] = to;
    int res = 1;
    for(int d=0; d<4; d++){
        res += fill(y+dy[d], x+dx[d], from, to, panel);
    }
    return res;
}
int nextcolor(int y, int x, int from, vector<vector<bool>> &used, vector<bool> &nc, vector<vector<int>> &panel){
    if(used[y][x]) return 0;
    used[y][x] = true;
    if(panel[y][x] != from){
        if(panel[y][x]!=-1) nc[panel[y][x]] = true;
        return 0;
    }
    int res = 1;
    for(int d=0; d<4; d++){
        res += nextcolor(y+dy[d], x+dx[d], from, used, nc, panel);
    }
    return res;
}
void solve(int step, vector<vector<int>> &panel){
    if(step >= ans) return;
    int h = (int)panel.size() -2;
    int w = (int)panel[0].size() -2;
    vector<bool> next(3, false);
    vector<vector<bool>> used(h+2, vector<bool>(w+2, false));
    int ret = nextcolor(1, 1, panel[1][1], used, next, panel);
    if(ret == h*w){
        ans = step;
        return;
    }
    for(int i=0; i<3; i++){
        if(i == panel[1][1]) continue;
        if(!next[i]) continue;
        auto tmp = panel;
        fill(1, 1, panel[1][1], i, tmp);
        solve(step+1, tmp);
    }
}

int main(){
    while(1){
        int w,h;
        cin >> w >> h;
        if(h == 0) break;

        ans = 19;
        vector<vector<int>> panel(h+2, vector<int>(w+2, -1));
        for(int i=1; i<=h; i++){
            for(int j=1; j<=w; j++){
                char c;
                cin >> c;
                if(c == 'R') panel[i][j] = 0;
                if(c == 'G') panel[i][j] = 1;
                if(c == 'B') panel[i][j] = 2;
            }
        }
        solve(0, panel);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 620
memory_kb: 3204
final_rank: 9

code_snippet: #include<stdio.h> 
#include<string.h>
#include<iostream>
#include<string>
#include <vector>
#include<algorithm>
#include <map>
#include <queue>

using namespace std;

int X, Y;
int dx[4] = { 0,0,-1,1 };
int dy[4] = { -1,1,0,0 };
char colors[3] = { 'R','G','B'};

class Cells
{
public:
	char data[10][10];
	Cells() { data[0][0] = 'X'; };
	Cells(char c[10][10])
	{
		for (size_t i = 0; i < Y; i++)
		{
			for (size_t j = 0; j < X; j++)
			{
				data[j][i] = c[j][i];
			}
		}
	}
	Cells(const Cells &cells)
	{
		for (size_t i = 0; i < Y; i++)
		{
			for (size_t j = 0; j < X; j++)
			{
				data[j][i] = cells.data[j][i];
			}
		}
	}
	void ChangeColor(char newColor, int x = 0,int y = 0)
	{
		char tmp = data[x][y];
		//
		//cout << x << "," << y << endl;
		data[x][y] = newColor;
		for (size_t i = 0; i < 4; i++)
		{
			int _x = x + dx[i];
			int _y = y + dy[i];
			if (_x >= 0 && _x < X && _y >= 0 && _y < Y && data[_x][_y] == tmp)
			{
				//cout << x << "," << y << " to " << _x << "," << _y << endl;
				ChangeColor(newColor, _x, _y);
			}
		}
	}
	bool Finished()
	{
		int color = data[0][0];
		for (size_t i = 0; i < Y; i++)
		{
			for (size_t j = 0; j < X; j++)
			{
				if (data[j][i] != color) return false;
			}
		}
		return true;
	}
};

int BFS(char g[10][10])
{
	queue<Cells> nodes;
	Cells node(g);
	if (node.Finished()) return 0;
	nodes.push(node);
	nodes.push(Cells());
	int floor = 1;
	while (!nodes.empty())
	{
		node = nodes.front();
		nodes.pop();
		if (node.data[0][0] == 'X')
		{
			floor++;
			nodes.push(Cells());
			continue;
		}
		for (size_t i = 0; i < 3; i++)
		{
			//
			//cout << colors[i] << " and " << node.data[0][0] <<  " 10 " << node.data[1][0] << " 01 " << node.data[0][1]<< endl;
			if (colors[i] == node.data[0][0]) continue;
			if (node.data[1][0] == node.data[0][0] || node.data[0][1] == node.data[0][0])
			{
				Cells newNode = node;
				//
				//cout << "change color : " << colors[i] << endl;
				newNode.ChangeColor(colors[i]);
				if (newNode.Finished()) return floor;
				nodes.push(newNode);
			}
			if (node.data[1][0] == colors[i] || node.data[0][1] == colors[i])
			{
				Cells newNode = node;
				//
				//cout << "change color : " << colors[i] << endl;
				newNode.ChangeColor(colors[i]);
				if (newNode.Finished()) return floor;
				nodes.push(newNode);
			}
		}
	}
	return -1;
}
int main()
{
	cin >> X >> Y;
	while (X || Y)
	{
		char g[10][10];
		for (size_t i = 0; i < Y; i++)
		{
			for (size_t j = 0; j < X; j++)
			{
				cin >> g[j][i];
			}
		}
		cout << BFS(g) << endl;
		cin >> X >> Y;
	}
}
accuracy: 1
time_ms: 260
memory_kb: 9708
final_rank: 8

code_snippet: #include<bits/stdc++.h>

using namespace std;

int X, Y, Ans;
int Dx[] = { 1,0,-1,0 };
int Dy[] = { 0,1,0,-1 };
bool Used[10][10];


void show(int s[10][10]) {
	char ch;

	for (int i = 0; i < Y; i++) {
		for (int j = 0; j < X; j++) {
			if (s[i][j] == 0) {
				ch = 'R';
			}
			else if (s[i][j] == 1) {
				ch = 'G';
			}
			else {
				ch = 'B';
			}
			cout << ch << " ";
		}
		cout << endl;
	}
	cout << "--\n";
}

bool judge(int(*p)[10]) {
	for (int i = 0; i < Y; ++i) {
		for (int j = 0; j < X; ++j) {
			if (p[i][j] != p[0][0]) {
				return false;
			}
		}
	}

	return true;
}

void nextState(int (*pSource)[10], int (*pTo1)[10], int (*pTo2)[10]) {
	int color1, color2, nowX, nowY;
	queue<pair<int, int> > convert;

	if (pSource[0][0] == 0) {
		color1 = 1;
		color2 = 2;
	}
	else if (pSource[0][0] == 1) {
		color1 = 0;
		color2 = 2;
	}
	else {
		color1 = 0;
		color2 = 1;
	}

	for (int i = 0; i < Y; ++i) {
		for (int j = 0; j < X; ++j) {
			pTo1[i][j] = pTo2[i][j] = pSource[i][j];
		}
	}
	
	memset(Used, false, sizeof(Used));
	convert.push(make_pair(0, 0));
	Used[0][0] = true;
	pTo1[0][0] = color1;
	pTo2[0][0] = color2;

	while (!convert.empty()) {
		pair<int, int> temp;
		temp = convert.front();
		convert.pop();

		for (int i = 0; i < 4; ++i) {
			nowX = temp.first + Dx[i];
			nowY = temp.second + Dy[i];

			if (nowX<0 || nowX>=X || nowY<0 || nowY>=Y) {
				continue;
			}
			if (Used[nowY][nowX]) {
				continue;
			}
			if (pSource[nowY][nowX] != pSource[0][0]) {
				continue;
			}
			Used[nowY][nowX] = true;
			pTo1[nowY][nowX] = color1;
			pTo2[nowY][nowX] = color2;
			convert.push(make_pair(nowX, nowY));
		}
	}

}

void solve(int (*p)[10], int cnt) {

	if (judge(p)) {
		Ans = min(Ans, cnt);
		return;
	}
	if (cnt >= Ans) {
		return;
	}

	int Tmp1[10][10], Tmp2[10][10];

	nextState(p, Tmp1, Tmp2);
	solve(Tmp1, cnt + 1);
	solve(Tmp2, cnt + 1);
}

int main() {
	char c;
	int mapData[10][10];

	while (cin >> X >> Y, X) {
		for (int i = 0; i < Y; ++i) {
			for (int j = 0; j < X; ++j) {
				cin >> c;
				if (c == 'R') {
					mapData[i][j] = 0;
				}
				else if (c == 'G') {
					mapData[i][j] = 1;
				}
				else if (c == 'B') {
					mapData[i][j] = 2;
				}
			}
		}
		//show(mapData);
		Ans = 20;
		solve(mapData, 0);
		cout << Ans << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 820
memory_kb: 3112
final_rank: 11

code_snippet: #include<bits/stdc++.h>

using namespace std;

int X, Y, Ans;
int Dx[] = { 1,0,-1,0 };
int Dy[] = { 0,1,0,-1 };
bool Used[10][10];


void show(int s[10][10]) {
	char ch;

	for (int i = 0; i < Y; i++) {
		for (int j = 0; j < X; j++) {
			if (s[i][j] == 0) {
				ch = 'R';
			}
			else if (s[i][j] == 1) {
				ch = 'G';
			}
			else {
				ch = 'B';
			}
			cout << ch << " ";
		}
		cout << endl;
	}
	cout << "--\n";
}

bool judge(int(*p)[10]) {
	for (int i = 0; i < Y; ++i) {
		for (int j = 0; j < X; ++j) {
			if (p[i][j] != p[0][0]) {
				return false;
			}
		}
	}

	return true;
}

void nextState(int (*pSource)[10], int (*pTo1)[10], int (*pTo2)[10]) {
	int color1, color2, nowX, nowY;
	queue<pair<int, int> > convert;

	if (pSource[0][0] == 0) {
		color1 = 1;
		color2 = 2;
	}
	else if (pSource[0][0] == 1) {
		color1 = 0;
		color2 = 2;
	}
	else {
		color1 = 0;
		color2 = 1;
	}

	for (int i = 0; i < Y; ++i) {
		for (int j = 0; j < X; ++j) {
			pTo1[i][j] = pTo2[i][j] = pSource[i][j];
		}
	}
	
	memset(Used, false, sizeof(Used));
	convert.push(make_pair(0, 0));
	Used[0][0] = true;
	pTo1[0][0] = color1;
	pTo2[0][0] = color2;

	while (!convert.empty()) {
		pair<int, int> temp;
		temp = convert.front();
		convert.pop();

		for (int i = 0; i < 4; ++i) {
			nowX = temp.first + Dx[i];
			nowY = temp.second + Dy[i];

			if (nowX<0 || nowX>=X || nowY<0 || nowY>=Y) {
				continue;
			}
			if (Used[nowY][nowX]) {
				continue;
			}
			if (pSource[nowY][nowX] != pSource[0][0]) {
				continue;
			}
			Used[nowY][nowX] = true;
			pTo1[nowY][nowX] = color1;
			pTo2[nowY][nowX] = color2;
			convert.push(make_pair(nowX, nowY));
		}
	}

}

void solve(int (*p)[10], int cnt) {

	if (judge(p)) {
		Ans = min(Ans, cnt);
		return;
	}
	if (cnt >= Ans) {
		return;
	}

	int Tmp1[10][10], Tmp2[10][10];

	nextState(p, Tmp1, Tmp2);
	solve(Tmp1, cnt + 1);
	solve(Tmp2, cnt + 1);
}

int main() {
	char c;
	int mapData[10][10];

	while (cin >> X >> Y, X) {
		for (int i = 0; i < Y; ++i) {
			for (int j = 0; j < X; ++j) {
				cin >> c;
				if (c == 'R') {
					mapData[i][j] = 0;
				}
				else if (c == 'G') {
					mapData[i][j] = 1;
				}
				else if (c == 'B') {
					mapData[i][j] = 2;
				}
			}
		}
		//show(mapData);
		Ans = 15;
		solve(mapData, 0);
		cout << Ans << endl;
	}

	return 0;
}
accuracy: 0.8
time_ms: 120
memory_kb: 3112
final_rank: 20

code_snippet: #include<bits/stdc++.h>

using namespace std;

int X, Y, Ans;
int Dx[] = { 1,0,-1,0 };
int Dy[] = { 0,1,0,-1 };
bool Used[10][10];


void show(int s[10][10]) {
	char ch;

	for (int i = 0; i < Y; i++) {
		for (int j = 0; j < X; j++) {
			if (s[i][j] == 0) {
				ch = 'R';
			}
			else if (s[i][j] == 1) {
				ch = 'G';
			}
			else {
				ch = 'B';
			}
			cout << ch << " ";
		}
		cout << endl;
	}
	cout << "--\n";
}

bool judge(int(*p)[10]) {
	for (int i = 0; i < Y; ++i) {
		for (int j = 0; j < X; ++j) {
			if (p[i][j] != p[0][0]) {
				return false;
			}
		}
	}

	return true;
}

void nextState(int (*pSource)[10], int (*pTo1)[10], int (*pTo2)[10]) {
	int color1, color2, nowX, nowY;
	queue<pair<int, int> > convert;

	if (pSource[0][0] == 0) {
		color1 = 1;
		color2 = 2;
	}
	else if (pSource[0][0] == 1) {
		color1 = 0;
		color2 = 2;
	}
	else {
		color1 = 0;
		color2 = 1;
	}

	for (int i = 0; i < Y; ++i) {
		for (int j = 0; j < X; ++j) {
			pTo1[i][j] = pTo2[i][j] = pSource[i][j];
		}
	}
	
	memset(Used, false, sizeof(Used));
	convert.push(make_pair(0, 0));
	Used[0][0] = true;
	pTo1[0][0] = color1;
	pTo2[0][0] = color2;

	while (!convert.empty()) {
		pair<int, int> temp;
		temp = convert.front();
		convert.pop();

		for (int i = 0; i < 4; ++i) {
			nowX = temp.first + Dx[i];
			nowY = temp.second + Dy[i];

			if (nowX<0 || nowX>=X || nowY<0 || nowY>=Y) {
				continue;
			}
			if (Used[nowY][nowX]) {
				continue;
			}
			if (pSource[nowY][nowX] != pSource[0][0]) {
				continue;
			}
			Used[nowY][nowX] = true;
			pTo1[nowY][nowX] = color1;
			pTo2[nowY][nowX] = color2;
			convert.push(make_pair(nowX, nowY));
		}
	}

}

void solve(int (*p)[10], int cnt) {

	if (judge(p)) {
		Ans = min(Ans, cnt);
		return;
	}
	if (cnt >= Ans) {
		return;
	}

	int Tmp1[10][10], Tmp2[10][10];

	nextState(p, Tmp1, Tmp2);
	solve(Tmp1, cnt + 1);
	solve(Tmp2, cnt + 1);
}

int main() {
	char c;
	int mapData[10][10];

	while (cin >> X >> Y, X) {
		for (int i = 0; i < Y; ++i) {
			for (int j = 0; j < X; ++j) {
				cin >> c;
				if (c == 'R') {
					mapData[i][j] = 0;
				}
				else if (c == 'G') {
					mapData[i][j] = 1;
				}
				else if (c == 'B') {
					mapData[i][j] = 2;
				}
			}
		}
		//show(mapData);
		Ans = 25;
		solve(mapData, 0);
		cout << Ans << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 1570
memory_kb: 3120
final_rank: 12

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

int main() {
    int h, w;
    using A = array<array<char, 12>, 12>;
    while(cin >> w >> h, w){
        A v;
        for (auto &&k : v) fill(k.begin(),k.end(), -1);
        for (int i = 1; i <= h; ++i) {
            for (int j = 1; j <= w; ++j) {
                char c;
                cin >> c;
                if(c == 'R') v[i][j] = 0;
                else if(c == 'G') v[i][j] = 1;
                else v[i][j] = 2;
            }
        }
        int ans = 18;
        array<int, 4> dx{-1, 1, 0, 0}, dy{0, 0, -1, 1};
        vector<pair<int, int>> hist;
        queue<pair<int, int>> Q;
        auto dfs = [&](int dep, A a, int prv, auto &&f) -> void {
            if(dep >= ans) return;
            for (int to = 0; to < 3; ++to) {
                if(a[1][1] == to) continue;
                A b = a;
                int cnt = 0;
                Q.emplace(1, 1);
                b[1][1] = to;
                while(!Q.empty()){
                    int y, x; tie(y, x) = Q.front(); Q.pop();
                    cnt++;
                    for (int k = 0; k < 4; ++k) {
                        if(b[y+dy[k]][x+dx[k]] == a[1][1]){
                            b[y+dy[k]][x+dx[k]] = to;
                            Q.emplace(y+dy[k], x+dx[k]);
                        }
                    }
                }
                if(cnt == h*w) ans = min(ans, dep);
                else if(prv < cnt) f(dep+1, b, cnt, f);
            }
        };
        dfs(0, v, 0, dfs);
        cout << ans << "\n";
    }


    return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 3120
final_rank: 5

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

int main() {
    int h, w;
    using A = array<array<char, 12>, 12>;
    while(cin >> w >> h, w){
        A v;
        for (auto &&k : v) fill(k.begin(),k.end(), -1);
        for (int i = 1; i <= h; ++i) {
            for (int j = 1; j <= w; ++j) {
                char c;
                cin >> c;
                if(c == 'R') v[i][j] = 0;
                else if(c == 'G') v[i][j] = 1;
                else v[i][j] = 2;
            }
        }
        int ans = h+w;
        array<int, 4> dx{-1, 1, 0, 0}, dy{0, 0, -1, 1};
        vector<pair<int, int>> hist;
        queue<pair<int, int>> Q;
        auto dfs = [&](int dep, A a, int prv, auto &&f) -> void {
            if(dep >= ans) return;
            for (int to = 0; to < 3; ++to) {
                if(a[1][1] == to) continue;
                A b = a;
                int cnt = 0;
                Q.emplace(1, 1);
                b[1][1] = to;
                while(!Q.empty()){
                    int y, x; tie(y, x) = Q.front(); Q.pop();
                    cnt++;
                    for (int k = 0; k < 4; ++k) {
                        if(b[y+dy[k]][x+dx[k]] == a[1][1]){
                            b[y+dy[k]][x+dx[k]] = to;
                            Q.emplace(y+dy[k], x+dx[k]);
                        }
                    }
                }
                if(cnt == h*w) ans = min(ans, dep);
                else if(prv < cnt) f(dep+1, b, cnt, f);
            }
        };
        dfs(0, v, 0, dfs);
        cout << ans << "\n";
    }


    return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 3168
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long int;
using P = pair<int, int>;
using P3 = pair<int,P>;
using PP = pair<P, P>;
constexpr int INF = 1<<29;
constexpr ll MOD = ll(1e9)+7;
constexpr int di[] = {0,1,0,-1};
constexpr int dj[] = {1,0,-1,0};

int h, w, ans;

void solve(vector<vector<int> > &a, vector<queue<P> > que, int cnt = -1){
    bool update = false;
    vector<P3> tmp;
    auto q = que;
    for(int k=0;k<3;k++){
        if(que[k].empty()) continue;
        update = true;
        tmp.clear();
        while(!que[k].empty()){
            P p = que[k].front();
            que[k].pop();
            int i = p.first, j = p.second;
            for(int x=0;x<4;x++){
                int ni = i+di[x], nj = j+dj[x];
                if(ni < 0 || ni >= h) continue;
                if(nj < 0 || nj >= w) continue;
                if(a[ni][nj] != 4){
                    tmp.push_back(P3(a[ni][nj],P(ni,nj)));
                    que[a[ni][nj]].push(P(ni,nj));
                    a[ni][nj] = 4;
                }
            }
        }
        if(ans >= cnt) solve(a, que, cnt+1);
        for(auto pp : tmp){
            int i = pp.second.first, j = pp.second.second;
            a[i][j] = pp.first;
        }
        que = q;
    }
    if(!update) ans = min(ans, cnt);
}

int main(){
    vector<vector<int> > a;
    while(cin >> w >> h, w){
        a.clear();
        a.resize(h, vector<int>(w));
        for(int i=0;i<h;i++){
            for(int j=0;j<w;j++){
                char c;
                cin >> c;
                if(c == 'R') a[i][j] = 0;
                if(c == 'G') a[i][j] = 1;
                if(c == 'B') a[i][j] = 2;
            }
        }
        ans = INF;
        vector<queue<P> > q(3);
        q[a[0][0]].push(P(0,0));
        a[0][0] = 4;
        solve(a, q);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 450
memory_kb: 3308
final_rank: 7

code_snippet: #include <iostream>
#include <vector>
#include <array>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <tuple>
#include <bitset>
#include <memory>
#include <cmath>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <numeric>
#include <climits>
#include <cfloat>

struct Coordinate {
	int x, y;
	std::vector<Coordinate> neighbors() const { return std::vector<Coordinate>{ Coordinate{x + 1, y}, Coordinate{x - 1, y}, Coordinate{x, y + 1}, Coordinate{x, y - 1} }; }
};
constexpr std::array<char, 3> Colors = { 'R', 'G', 'B' };
int min_step(std::vector<std::vector<char>>& state, const int current_step = 0, int current_min = 30) {
	if (current_step >= current_min) return current_min;
	if (std::all_of(state.begin(), state.end(), [&state](const std::vector<char>& line) {return std::all_of(line.begin(), line.end(), [&state](const char c) {return c == state[0][0]; }); })) return current_step;
	auto initial = state[0][0];
	std::vector<std::vector<bool>> is_join(state.size(), std::vector<bool>(state.front().size(), false));
	is_join[0][0] = true;
	std::queue<Coordinate> queue; queue.push(Coordinate{ 0, 0 });
	while (!queue.empty()) {
		auto top = queue.front(); queue.pop();
		for (auto next : top.neighbors()) if (0 <= next.y && next.y < state.size() && 0 <= next.x && next.x < state.front().size() && !is_join[next.y][next.x]) {
			if (state[next.y][next.x] == initial) {
				is_join[next.y][next.x] = true;
				queue.push(next);
			}
		}
	}
	auto diff = std::distance(Colors.begin(), std::find(Colors.begin(), Colors.end(), initial));
	for (auto c = 1; c < 3; ++c) {
		for (auto i = 0; i < state.size(); ++i) for (auto j = 0; j < state[i].size(); ++j) {
			if (is_join[i][j]) state[i][j] = Colors[(c + diff) % 3];
		}
		current_min = min_step(state, current_step + 1, current_min);
	}
	for (auto i = 0; i < state.size(); ++i) for (auto j = 0; j < state[i].size(); ++j) if (is_join[i][j]) state[i][j] = initial;
	return current_min;
}
int main() {
	std::cin.tie(0); std::cin.sync_with_stdio(false);
	while (true) {
		int x, y; std::cin >> x >> y; if (x == 0 && y == 0) break;
		std::vector<std::vector<char>> state(y, std::vector<char>(x)); for (auto& line : state) for (auto& cell : line) std::cin >> cell;
		std::cout << min_step(state) << '\n';
	}
}
accuracy: 1
time_ms: 2160
memory_kb: 3192
final_rank: 15

code_snippet: #include <cstdio>
#include <cstdint>
#include <vector>
#include <algorithm>
#include <string>
#include <utility>
#include <tuple>
#include <queue>

constexpr size_t m1 = -1;
constexpr size_t di[] = {m1, 0, 1, 0};
constexpr size_t dj[] = {0, m1, 0, 1};

using ban = std::vector<std::string>;
using zahyo = std::pair<size_t, size_t>;

bool nuru(ban& t, char c) {
  char c0 = t[0][0];
  size_t h = t.size();
  size_t w = t[0].length();
  std::queue<zahyo> q;
  q.emplace(0, 0);
  t[0][0] = c;
  while (!q.empty()) {
    size_t i, j;
    std::tie(i, j) = q.front();
    q.pop();
    for (int k = 0; k < 4; ++k) {
      size_t ni = i + di[k];
      size_t nj = j + dj[k];
      if (!(ni < h && nj < w)) continue;
      if (t[ni][nj] != c0) continue;
      t[ni][nj] = c;
      q.emplace(ni, nj);
    }
  }

  size_t res = 0;
  for (size_t i = 0; i < h; ++i)
    for (size_t j = 0; j < w; ++j)
      if (t[i][j] == c) ++res;

  return (res == h * w);
}

int testcase_ends() {
  size_t H, W;
  scanf("%zu %zu", &W, &H);
  if (H == 0 && W == 0) return 1;

  std::vector<std::string> s(H, std::string(W, '@'));
  for (size_t i = 0; i < H; ++i)
    for (size_t j = 0; j < W; ++j)
      scanf(" %c", &s[i][j]);

  {
    size_t count = 0;
    for (size_t i = 0; i < H; ++i)
      for (size_t j = 0; j < W; ++j)
        if (s[0][0] == s[i][j]) ++count;

    if (count == H * W) return puts("0"), 0;
  }

  std::string const color = "RGB";

  std::queue<std::pair<ban, int>> q;
  q.emplace(s, 0);
  while (!q.empty()) {
    ban b;
    size_t res;
    std::tie(b, res) = q.front();
    q.pop();
    for (char c: color) {
      if (b[0][0] == c) continue;
      ban t = b;
      if (nuru(t, c)) return !printf("%zu\n", res+1);
      q.emplace(t, res+1);
    }
  }
  return 0;
}

int main() {
  while (!testcase_ends()) {}
}
accuracy: 1
time_ms: 910
memory_kb: 74576
final_rank: 17

code_snippet: #include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
#define int long long int
const int INF = 1001001001001001LL;
const int MOD = 1000000007;

int di[4] = {1, 0, -1, 0};
int dj[4] = {0, -1, 0, 1};

int x, y;

void dfs(int i, int j, char cur, char next, vector<vector<char>> &vec){
    
    vec[i][j] = next;
    for(int h = 0; h < 4; h++){
        int ni = i + di[h];
        int nj = j + dj[h];
        if(ni < 0 || y <= ni || nj < 0 || x <= nj) continue;

        if(vec[ni][nj] == cur) dfs(ni, nj, cur, next, vec);
    }
}



signed main(){
    
    while(1){
    cin >> x >> y;
    if(x == 0) break;
    vector<vector<char>> g(y, vector<char> (x));
    for(int i = 0; i < y; i++){
        for(int j = 0; j < x; j++){
            cin >> g[i][j];
       }
    }
    
    set<vector<vector<char>>> st;
    queue<pair<int, vector<vector<char>>>> que;
    que.push({0, g});
    st.insert(g);
    
    while(1){
        
        auto tmp = que.front();
        auto vec = tmp.second;
        int cost = tmp.first;
        que.pop();
            
        /*cout << endl;
        for(int i = 0; i < y; i++){
            for(int j = 0; j < x; j++){
                cout << vec[i][j] << " ";
            }
            cout << endl;
        }
        cout << endl;
        */

        bool flag = true;
        char cur = vec[0][0];
        for(int i = 0; i < y; i++){
            for(int j = 0; j < x; j++){
                if(vec[i][j] != cur) flag = false;
            }
        }

        if(flag){
            cout << cost << endl;
            break;
        }
        
        if(cur != 'R'){
            auto vec2 = vec;
            dfs(0, 0, cur, 'R', vec2);

            if(st.find(vec2) == st.end()){
                que.push({cost + 1, vec2});
                st.insert(vec2);
            }
        }
        
        if(cur != 'B'){
            auto vec2 = vec;
            dfs(0, 0, cur, 'B', vec2);
            if(st.find(vec2) == st.end()){

                que.push({cost + 1, vec2});
                st.insert(vec2);
            }
        }
        
        if(cur != 'G'){
            auto vec2 = vec;
            dfs(0, 0, cur, 'G', vec2);
            if(st.find(vec2) == st.end()){

                que.push({cost + 1, vec2});
                st.insert(vec2);
            }
        }
        
    }
    }
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 7784
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;

int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};

using vc = vector<vector<char>>;

void dfs(vc &c, int y, int x, char oldc, char newc) {
  if(y < 0 || y >= c.size() || x < 0 || x >= c[0].size()) return;
  if(c[y][x] != oldc) return;
  c[y][x] = newc;

  for(int i = 0; i < 4; ++i) {
    int ny = y + dy[i], nx = x + dx[i];  
    dfs(c, ny, nx, oldc, newc);
  }
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  char tmp[] = {'R', 'G', 'B'};

  int x, y;
  while(cin >> x >> y, y != 0) {
    vc c(y, vector<char>(x));
    for(int i = 0; i < y; ++i) {
      for(int j = 0; j < x; ++j) {
        cin >> c[i][j];
      }
    }

    int ans = 1e9;
    queue<vc> que;
    que.push(c);
    map<vc, int> mp;
    mp[c] = 0;

    while(!que.empty()) {
      vc s = que.front();
      que.pop();

      {
        bool ok = true;
        for(int i = 0; i < y; ++i) {
          for(int j = 0; j < x; ++j) {
            if(s[0][0] != s[i][j]) ok = false;
          }
        }

        if(ok) {
          ans = mp[s];
          break;
        }
      }

      for(int i = 0; i < 3; ++i) {
        if(s[0][0] == tmp[i]) continue;

        vc nc = s;

        dfs(nc, 0, 0, s[0][0], tmp[i]);
        if(!mp.count(nc)) {
          mp[nc] = mp[s] + 1;
          que.push(nc);
        }
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 80
memory_kb: 7872
final_rank: 4

code_snippet: #include<iostream>
#include<queue>
#include<vector>
using namespace std;
#define inRange(x,a,b) (a <= x && x < b)

int dx[8] = {0,0,1,-1,1,1,-1,-1};
int dy[8] = {1,-1,0,0,1,-1,1,-1};

struct board{
    int y, x;
    vector<vector<char>> v;
    board(int i, int j) : y(i), x(j) {
        v.resize(i, vector<char>(j));
    }
};

bool check(vector<vector<char>> v, int siz){
    int cnt = 0;
    for(int i = 0; i < v.size(); i++){
        for(int j = 0; j < v[i].size(); j++){
            cnt += (v[i][j] == v[0][0]);
        }
    }
    return cnt == siz;
}

int main(){
    int x, y;
    while(cin >> x >> y, x+y){
        char mat[y][x];
        board ini(y, x);
        for(int i = 0; i < y; i++){
            for(int j = 0; j < x; j++){
                cin >> mat[i][j];
                ini.v[i][j] = mat[i][j];
            }
        }

        queue<pair<int, board>> q;
        q.push({0, ini});

        int ans = -1;
        while(ans == -1 && !q.empty()){
            auto p = q.front(); q.pop();
            
            if(check(p.second.v, x*y)){
                ans = p.first;
                break;
            }

            for(int i = 0; i < 3; i++){
                char from = p.second.v[0][0], to = "RGB"[i];
                if(from == to)    continue;
                board next = p.second;
                queue<pair<int,int>> pq;
                pq.push({0,0});
                while(!pq.empty()){
                    pair<int,int> now = pq.front(); pq.pop();
                    if(next.v[now.first][now.second] == to) continue;
                    next.v[now.first][now.second] = to;
                    for(int k = 0; k < 4; k++){
                        int ni = now.first + dx[k], nj = now.second + dy[k];
                        if(inRange(ni, 0, y) && inRange(nj, 0, x) && next.v[ni][nj] == from){
                            pq.push({ni,nj});
                        }
                    } 
                }

                if(check(next.v, x*y)){
                    ans = p.first+1;
                    break;
                }
                q.push({p.first+1, next});
            }
        }

        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1210
memory_kb: 76684
final_rank: 19

code_snippet: #include<iostream>
#include<queue>
#include<vector>
using namespace std;
#define inRange(x,a,b) (a <= x && x < b)

int dx[8] = {0,0,1,-1,1,1,-1,-1};
int dy[8] = {1,-1,0,0,1,-1,1,-1};

struct board{
    int y, x;
    vector<vector<char>> v;
    board(int i, int j) : y(i), x(j) {
        v.resize(i, vector<char>(j));
    }
};

int main(){
    int x, y;
    while(cin >> x >> y, x+y){
        char mat[y][x];
        board ini(y, x);
        for(int i = 0; i < y; i++){
            for(int j = 0; j < x; j++){
                cin >> mat[i][j];
                ini.v[i][j] = mat[i][j];
            }
        }

        queue<pair<int, board>> q;
        q.push({0, ini});

        int ans = -1;
        while(ans == -1 && !q.empty()){
            auto p = q.front(); q.pop();
            int cnt = 0;
            char c = p.second.v[0][0];
            for(int i = 0; i < y; i++){
                for(int j = 0; j < x; j++){
                    if(c == p.second.v[i][j])   cnt++;
                }
            }
            if(cnt == x*y){
                ans = p.first;
                break;
            }

            for(int i = 0; i < 3; i++){
                char from = p.second.v[0][0], to = "RGB"[i];
                if(from == to)    continue;
                board next = p.second;
                queue<pair<int,int>> pq;
                pq.push({0,0});
                while(!pq.empty()){
                    pair<int,int> now = pq.front(); pq.pop();
                    if(next.v[now.first][now.second] == to) continue;
                    next.v[now.first][now.second] = to;
                    for(int k = 0; k < 4; k++){
                        int ni = now.first + dx[k], nj = now.second + dy[k];
                        if(inRange(ni, 0, y) && inRange(nj, 0, x) && next.v[ni][nj] == from){
                            pq.push({ni,nj});
                        }
                    } 
                }

                cnt = 0;
                c = to;
                for(int i = 0; i < y; i++) for(int j = 0; j < x; j++)   cnt += (next.v[i][j] == c);
                if(cnt == x*y){
                    ans = p.first+1;
                    break;
                }
                q.push({p.first+1, next});
            }
        }

        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 960
memory_kb: 76920
final_rank: 18