Problem:
Identically Colored Panels Connection
Dr. Fukuoka has invented fancy panels.

Each panel has a square shape of a unit size and 
has one of the six colors, namely, yellow, pink, red, purple, green and blue.

The panel has two remarkable properties.

One property is that, when two or more panels with the same color
are placed adjacently, their touching edges melt a little
and they are fused each other.
The fused panels are united into a polygonally shaped panel.


The other property is that the color of a panel can be changed 
to one of six colors by giving an electrical shock.
The resulting color can be controlled by its waveform.
The electrical shock to an already united panel changes
the color of the whole to a specified single color.
Since he wants to investigate the strength with respect to the
color and the size of a united panel compared to unit panels,
he tries to unite panels into a polygonal panel with a specified color.
Figure C-1: panels and their initial colors
Since many panels are simultaneously synthesized and generated on a base plate 
through some complex chemical processes,
the fabricated panels are randomly colored and
they are arranged in a rectangular shape on the base plate  (Figure C-1).

Note that the two purple (color 4) panels in Figure C-1 are
already united at the initial state since they are 
adjacent to each other.
Installing  electrodes to a panel, and
changing its color several times by giving electrical shocks
according to an appropriate sequence for a specified target color,
he can make a united panel merge the adjacent panels 
to unite them step by step
and can obtain a larger panel with the target color.

Unfortunately, panels will be broken when
they are struck by the sixth electrical shock.

That is, he can change the color of a panel or a united panel only 
five times.
Let us consider a case
where the panel at the upper left corner of the panel configuration
(Figure C-1) is attached with the electrodes.
First, changing the color of the panel from yellow to blue,
the two adjacent panels are fused into a united panel (Figure C-2).
Figure C-2: 
Change of the color of the panel at the upper left corner,
from yellow (color 1) to blue (color 6).
Second, changing the color of the upper left united panel from blue
to red, a united red panel that consists of three unit panels is newly formed
(Figure C-3).
Then, changing the color of the united panel from red to purple,
panels are united again to form a united panel of five unit panels
(Figure C-4).
Figure C-3: 
Change of the color of the panel at the upper left corner,
from blue (color 6) to red (color 3).
Figure C-4: 
Change of the color of the panel at the upper left corner,
from red (color 3) to purple (color 4).
Furthermore, through making a pink united panel in Figure C-5 by
changing the color from purple to pink, 
then, the green united panel in Figure C-6 is obtained
by changing the color from pink to green.
The green united panel consists of ten unit panels.
F
...(truncated)

Submitted solutions:

code_snippet: #include <algorithm>
#include <cstdio>
#include <cstring>

using std::max;

int N, M, target, a[8][8], f, t, ans, x[64], y[64];

int w[10];

void copy(int b[8][8], int a[8][8]) {
	for(int i = 0; i < N; ++i) {
		for(int j = 0; j < M; ++j) {
			b[i][j] = a[i][j];
		}
	}
}

void print() {
	for(int i = 0; i < N; ++i) {
		for(int j = 0; j < M; ++j) {
			printf("%d ", a[i][j]);
		}
		puts("");
	}
	puts("");
}

bool inRange(int x, int y) {
	return x >= 0 && x < N && y >= 0 && y < M;
}

int work(int color) {
	bool hsh[8][8];
	for(int i = 0; i < N; ++i) for(int j = 0; j < M; ++j) hsh[i][j] = false;
	f = t = 0;
	hsh[0][0] = true;
	x[0] = 0;
	y[0] = 0;
	++t;
	while(f < t) {
		for(int dx = -1; dx <= 1; ++dx) {
			for(int dy = -1; dy <= 1; ++dy) {
				if(abs(dx) + abs(dy) == 1 && inRange(x[f] + dx, y[f] + dy)) {
					int xx = x[f] + dx;
					int yy = y[f] + dy;
					if(a[xx][yy] == a[0][0] && !hsh[xx][yy]) {
						x[t] = xx;
						y[t] = yy;
						hsh[xx][yy] = true;
						++t;
					}
				}
			}
		}
		++f;
	}
	for(int j = 0; j < t; ++j) {
		a[x[j]][y[j]] = color;
	}
	return f;
}

void dfs(int dep) {
//	printf("[%d]\n", dep);
	int b[8][8];
	copy(b, a);
	if(dep < 4) {
		for(int i = 1; i <= 6; ++i) {
			work(i);
			dfs(dep + 1);
			copy(a, b);
		}
		return;
	}
	work(target);
	ans = max(ans, work(target));
}

int main() {
	// freopen("input", "r", stdin);
	// freopen("output", "w", stdout);
	while(scanf("%d%d%d", &N, &M, &target), N && M) {
		for(int i = 0; i < N; ++i) {
			for(int j = 0; j < M; ++j) {
				scanf("%d", a[i] + j);
			}
		}
		ans = 0;
		dfs(0);
		printf("%d\n", ans);
	}
	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 2808
final_rank: 1

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

bool solve() {
    int H, W, C;
    cin >> H >> W >> C;
    if (H == 0) return false;
    vector<vector<int>> P(H, vector<int>(W));
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) cin >> P[i][j];
    }
    int ans = 0;
    auto rec = [&] (auto rec, int k, vector<vector<int>> P) -> void {
        vector<vector<bool>> vis(H, vector<bool>(W, false));
        vis[0][0] = true;
        queue<pair<int, int>> q;
        q.emplace(0, 0);
        int D[5] = {0, 1, 0, -1, 0};
        vector<pair<int, int>> bfs;
        while (q.size()) {
            auto [r, c] = q.front();
            q.pop();
            bfs.emplace_back(r, c);
            for (int d = 0; d < 4; d++) {
                int nr = r + D[d], nc = c + D[d + 1];
                if (0 <= nr && nr < H && 0 <= nc && nc < W) {
                    if (!vis[nr][nc] && P[nr][nc] == P[0][0]) {
                        vis[nr][nc] = true;
                        q.emplace(nr, nc);
                    }
                }
            }
        }
        if (k == 5) {
            if (P[0][0] == C) ans = max(ans, (int)bfs.size());
            return;
        }
        for (int c = 1; c <= 6; c++) {
            auto Q = P;
            for (auto [i, j] : bfs) Q[i][j] = c;
            rec(rec, k + 1, Q);
        }
    };
    rec(rec, 0, P);
    cout << ans << endl;
    return true;
}

int main() {
    while (solve()) {}
}
accuracy: 1
time_ms: 1700
memory_kb: 3584
final_rank: 16

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

const long long MOD1 = 1000000007;
const long long MOD2 = 998244353;
#define all(v) v.begin(), v.end()
#define rall(a) a.rbegin(), a.rend()
#define fi first
#define se second
#define endl "\n"

#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)

template <typename T>
using vc = vector<T>; // prioriy_queueに必要なのでここにこれ書いてます
template <typename T>
using vv = vc<vc<T>>;
#define int long long
using ll = long long;
ll INF = 2e18;

#ifdef ONLINE_JUDGE
// ジャッジ環境ではデバッグマクロを無効化
#define debug_x(x) \
    do             \
    {              \
    } while (0)
#define debug_vc(v) \
    do              \
    {               \
    } while (0)
#define debug_vv(v) \
    do              \
    {               \
    } while (0)
#else
// ローカルではデバッグ出力
#define debug_x(x) cout << #x << " = " << (x) << endl
#define debug_vc(v)                    \
    {                                  \
        cout << #v << endl;            \
        ll n = size(v);                \
        rep(i, n) cout << v[i] << ' '; \
        cout << endl;                  \
    } // 一次元配列を出力する
#define debug_vv(v)                                        \
    {                                                      \
        cout << #v << endl;                                \
        ll n = size(v);                                    \
        rep(i, n)                                          \
        {                                                  \
            rep(j, size(v[i])) { cout << v[i][j] << ' '; } \
            cout << endl;                                  \
        }                                                  \
    } // 二次元配列を出力する
#endif

#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define rrep(i, n) for (ll i = 1; i <= (n); ++i)
#define drep(i, n) for (ll i = (n) - 1; i >= 0; --i)
#define nfor(i, s, n) for (ll i = s; i < n; i++)        // i=s,s+1...n-1 ノーマルfor
#define dfor(i, s, n) for (ll i = (s) - 1; i >= n; i--) // s-1スタートでnまで落ちる

using ld = long double;
using bl = bool;

template <class T>
using pq = priority_queue<T, vc<T>>; // 大きい順
template <class T>
using pq_g = priority_queue<T, vc<T>, greater<T>>; // 小さい順

using vl = vc<ll>;
using vvl = vv<ll>;
using vvvl = vv<vl>;
using vvvvl = vv<vvl>;
using vs = vc<string>;
using vvs = vv<string>;
using vb = vc<bl>;
using vvb = vv<bl>;
using vvvb = vv<vb>;
using vld = vc<ld>;
using vvld = vv<ld>;
using vvvld = vv<vld>;
using P = pair<ll, ll>;
using vP = vc<P>;
using vvP = vc<vP>;
using vvvP = vv<vP>;

#define pb push_back

#define YES cout << "Yes" << endl
#define NO cout << "No" << endl
#define YN                     \
    {                          \
        cout << "Yes" << endl; \
    }                          \
    else                       \
    {                          \
        cout << "No" << endl;  \
    } // if(a==b)YN;
#define dame cout << -1 << endl

string dir = "DRUL";   // 第4象限の場合
vl di = {1, 0, -1, 0}; // vl di={1,1,0,-1,-1,-1,0,1};
vl dj = {0, 1, 0, -1}; // vl dj={0,1,1,1,0,-1,-1,-1};

bool out_grid(ll i, ll j, ll h, ll w)
{ // trueならcontinue
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

ll ans = -1;
ll h, w, c;

void dfs(vl &col,vvl &p)
{
    vvl tmp = p;
    bl isFinished = true;
    rep(i, 5)
    {
        col[i]++;
        if (col[i] == 7)
        {
            col[i] = 1;
        }
        else
        {
            isFinished = false;
            break;
        }
    }
    if(isFinished){
        return;
    }
    // debug_vc(col);
    rep(color, 5)
    {
        // debug_vv(tmp);
        vvl dist(h, vl(w));
        dist[0][0] = tmp[0][0];
        tmp[0][0] = col[color];
        queue<P> que;
        que.push({0, 0});
        while (!que.empty())
        {
            auto [i, j] = que.front();
            que.pop();
            // xに隣接する頂点についてfor文
            rep(k, 4)
            {
                ll ni = i + di[k];
                ll nj = j + dj[k];
                if (out_grid(ni, nj, h, w))
                    continue;
                if(dist[ni][nj]==0&&tmp[ni][nj]==dist[i][j]){
                    que.push({ni,nj});
                    tmp[ni][nj] = col[color];
                    dist[ni][nj] = dist[i][j];
                }
            }
        }
    }
    if(tmp[0][0]==c){
        ll cnt = 1;
        vvl dist(h, vl(w));
        dist[0][0] = c;
        queue<P> que;
        que.push({0, 0});
        while (!que.empty())
        {
            auto [i, j] = que.front();
            que.pop();
            // xに隣接する頂点についてfor文
            rep(k, 4)
            {
                ll ni = i + di[k];
                ll nj = j + dj[k];
                if (out_grid(ni, nj, h, w))
                    continue;
                if(dist[ni][nj]==0&&tmp[ni][nj]==dist[i][j]){
                    que.push({ni,nj});
                    dist[ni][nj] = dist[i][j];
                    cnt++;
                }
            }
        }
        ans = max(cnt,ans);
        // debug_x(ans);
    }
    dfs(col,p);
    return;
}

bl solve()
{
    cin >> h >> w >> c;
    if (h == 0 && w == 0 && c == 0)
        return 0;
    ans = -1;
    vvl p(h, vl(w));
    rep(i, h)
    {
        rep(j, w)
        {
            cin >> p[i][j];
        }
    }
    // 6^5通りすべて試す
    vl col(5, 1);
    col[0] = 0;
    dfs(col,p);
    cout << ans << endl;
    return 1;
}

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    while (true)
    {
        if (!solve())
            break;
    }
    return 0;
}

/*
shift+alt+Fで成形
f2で変数名変更

スニペット
basic
 m:atcoder以外用
 ma:ABC/ARC用
 mahc:AHC用
math
 floor:床関数
 ceil:天井関数
 comv:二項係数
 modpow: a^b mod m
 GCD:最大公約数
 extGCD:拡張ユークリッド互除法
 PFD:素因数分解
 isprime:エラトステネスの篩
 matrixpow:行列累乗
data_structure
 seg:セグメント木
technic
 Compress:座標圧縮
 runlength:ランレングス圧縮
graph
 warshall:ワーシャルフロイド法
 dfs:深さ優先探索
 bfs:幅優先探索
 LCA:最近共通祖先
*/
accuracy: 1
time_ms: 3520
memory_kb: 12156
final_rank: 20

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

#include <algorithm>
#include <cassert>
#include <vector>

namespace atcoder {

struct dsu {
  public:
    dsu() : _n(0) {}
    explicit dsu(int n) : _n(n), parent_or_size(n, -1) {}

    int merge(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        int x = leader(a), y = leader(b);
        if (x == y) return x;
        if (-parent_or_size[x] < -parent_or_size[y]) std::swap(x, y);
        parent_or_size[x] += parent_or_size[y];
        parent_or_size[y] = x;
        return x;
    }

    bool same(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        return leader(a) == leader(b);
    }

    int leader(int a) {
        assert(0 <= a && a < _n);
        return _leader(a);
    }

    int size(int a) {
        assert(0 <= a && a < _n);
        return -parent_or_size[leader(a)];
    }

    std::vector<std::vector<int>> groups() {
        std::vector<int> leader_buf(_n), group_size(_n);
        for (int i = 0; i < _n; i++) {
            leader_buf[i] = leader(i);
            group_size[leader_buf[i]]++;
        }
        std::vector<std::vector<int>> result(_n);
        for (int i = 0; i < _n; i++) {
            result[i].reserve(group_size[i]);
        }
        for (int i = 0; i < _n; i++) {
            result[leader_buf[i]].push_back(i);
        }
        result.erase(
            std::remove_if(result.begin(), result.end(),
                           [&](const std::vector<int>& v) { return v.empty(); }),
            result.end());
        return result;
    }

  private:
    int _n;
    std::vector<int> parent_or_size;

    int _leader(int a) {
        if (parent_or_size[a] < 0) return a;
        return parent_or_size[a] = _leader(parent_or_size[a]);
    }
};

}  // namespace atcoder

using namespace std;
using namespace atcoder;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define rrep(i,start,end) for (ll i = start;i >= (ll)(end);i--)
#define repn(i,end) for(ll i = 0; i <= (ll)(end); i++)
#define reps(i,start,end) for(ll i = start; i < (ll)(end); i++)
#define repsn(i,start,end) for(ll i = start; i <= (ll)(end); i++)
#define each(p,a) for(auto &p:a)
typedef vector<ll> vll;
typedef vector<pair<ll ,ll>> vpll;
typedef vector<vector<ll>> vvll;
typedef set<ll> sll;
typedef map<ll , ll> mpll;
typedef pair<ll ,ll> pll;
typedef tuple<ll , ll , ll> tpl3;
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define Str(...) string __VA_ARGS__; input(__VA_ARGS__)
#define Ch(...) char __VA_ARGS__; input(__VA_ARGS__)
#define all(a)  (a).begin(),(a).end()
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define sz(x) (ll)x.size()
// << std::fixed << std::setprecision(10)
const ll INF = 1LL << 60;
const ld EPS = 1e-9;
 
ll lceil(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b)+1;}else{return -((-a)/b);}}
ll lfloor(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b);}else{return -((-a)/b)-1;}}
inline ll positive_mod(ll a,ll m){return (a % m + m)%m;}
inline ll popcnt(ull a){ return __builtin_popcountll(a);}
//0indexed
inline ll topbit(ll a){assert(a != 0);return 63 - __builtin_clzll(a);}
inline ll smlbit(ll a){assert(a != 0);return __builtin_ctzll(a);}
template<class T> bool chmin(T& a, T b){if(a > b){a = b;return true;}return false;}
template<class T> bool chmax(T& a, T b){if(a < b){a = b;return true;}return false;}
template<typename T> std::istream &operator>>(std::istream&is,std::vector<T>&v){for(T &in:v){is>>in;}return is;}
template<typename T> std::ostream &operator<<(std::ostream&os,const std::vector<T>&v){for(auto it=std::begin(v);it!=std::end(v);){os<<*it<<((++it)!=std::end(v)?" ":"");}return os;}
template<typename T1, typename T2>std::ostream &operator<< (std::ostream &os, std::pair<T1,T2> p){os << "{" << p.first << "," << p.second << "}";return os;}
template<class... T>void input(T&... a){(cin >> ... >> a);}
void print(){cout << endl;}
template<class T, class... Ts>void print(const T& a, const Ts&... b){cout << a;((cout << ' ' << b), ...);cout << endl;}
template<class T> void pspace(const T& a){ cout << a << ' ';}
void perr(){cerr << endl;}
template<class T, class... Ts>void perr(const T& a, const Ts&... b){cerr << a;((cerr << ' ' << b), ...);cerr << endl;}
void yes(bool i = true){ return print(i?"yes":"no"); }
void Yes(bool i = true){ return print(i?"Yes":"No"); }
void YES(bool i = true){ return print(i?"YES":"NO"); }
template <class T> vector<T> &operator++(vector<T> &v) {for(auto &e : v) e++;return v;}
template <class T> vector<T> operator++(vector<T> &v, signed) {auto res = v;for(auto &e : v) e++;return res;}
template <class T> vector<T> &operator--(vector<T> &v) {for(auto &e : v) e--;return v;}
template <class T> vector<T> operator--(vector<T> &v, signed) {auto res = v;for(auto &e : v) e--;return res;}
//grid探索用
vector<ll> _ta = {0,0,1,-1,1,1,-1,-1};
vector<ll> _yo = {1,-1,0,0,1,-1,1,-1};
bool isin(ll now_i,ll now_j,ll h,ll w){return (0<=now_i && now_i < h && 0 <= now_j && now_j < w);}
  
ll lpow(ll x,ll n){ll ans = 1;while(n >0){if(n & 1)ans *= x;x *= x;n >>= 1;}return ans;}
ll Modlpow(ll x,ll n,ll m){ll ans = 1;ll a = x%m;while(n >0){if(n & 1){ans *= a;ans%= m;}a *= a;a %= m;n >>= 1;}return ans;} 
const ll MOD9 = 998244353LL;
const ll MOD10 = 1000000007LL;

// for AOJ or ICPC or etc..
template<class Tp>
bool zero (const Tp &x) {
    return x == 0;
}

template<class Tp, class... Args>
bool zero (const Tp &x, const Args& ...args) {
    return zero(x) and zero(args...);
}



void solve(ll h,ll w,ll c){
  vvll a(h,vll(w));
  rep(i,h){
    cin >> a[i];
  }

  ll ans =0;
  
  auto clc = [&](auto clc,vvll state,ll num)->void {
    if(num == 5){//5回目
      //cで塗って終わり
      vvll found(h,vll(w));
      ll basec = state[0][0];
      auto dfs = [&](auto dfs, ll i,ll j)->void {
        found[i][j] = 1; 
        state[i][j] = c;
        rep(k,4){
          ll ny = i + _ta[k];
          ll nx = j + _yo[k];
          if(isin(ny,nx,h,w)&& state[ny][nx] == basec && found[ny][nx] == 0){
            dfs(dfs,ny,nx);
          }
        } 
      };
      dfs(dfs,0,0);
      dsu uf(h*w);
      rep(i,h){
        rep(j,w){
          rep(k,4){
            ll ny = i+_ta[k];
            ll nx = j + _yo[k];
            if(isin(ny,nx,h,w)&&state[i][j] == state[ny][nx]){
              uf.merge(i*w+j,ny*w+nx);
            }
          }
        }
      }
      chmax(ans,(ll)uf.size(0));
      // if(chmax(ans,(ll)uf.size(0))){
      //   rep(i,h){
      //     cout << state[i] << endl;
      //   }
      //   cout << endl;
      // }
      return ;
    }

    //6色試す
    repsn(nc,1,6){
      vvll nstate = state;
      vvll found(h,vll(w));
      ll basec = state[0][0];
      auto dfs = [&](auto dfs, ll i,ll j)->void {
        found[i][j] = 1; 
        nstate[i][j] = nc;
        rep(k,4){
          ll ny = i + _ta[k];
          ll nx = j + _yo[k];
          if(isin(ny,nx,h,w)&& state[ny][nx] == basec && found[ny][nx] == 0){
            dfs(dfs,ny,nx);
          }
        } 
      };
      dfs(dfs,0,0);
      clc(clc,nstate,num+1);
    }
  };
  clc(clc,a,1);
  cout << ans << endl;
}

 
int main(){
  ios::sync_with_stdio(false);cin.tie(nullptr);
  while(true){
    LL(h,w,c);
    if(zero(h,w,c))break;
    solve(h,w,c);
  }
}
accuracy: 1
time_ms: 390
memory_kb: 3584
final_rank: 7

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

using ll = long long;
using vi = vector<int>;
using vl = vector<long long>;
using vs = vector<string>;
using vc = vector<char>;
using vb = vector<bool>;
using vpii = vector<pair<int, int>>;
using vpll = vector<pair<long long, long long>>;
using vvi = vector<vector<int>>;
using vvl = vector<vector<long long>>;
using vvc = vector<vector<char>>;
using vvvi = vector<vector<vector<int>>>;
using pii = pair<int, int>;
using vvb = vector<vector<bool>>;
using Graph = vector<vector<ll>>;
const ll LINF = 1001002003004005006ll;
const int INF = 1001001001;
const int MOD = 998244353;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep3(i, m, n) for (int i = (m); i < (int)(n); i++)
#define rrep(i, m, n) for (int i = (m); i >= (int)(n); i--)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()

template <typename T1, typename T2> inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }
template <typename T1, typename T2> inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }

vi dx4 = {1, 0, -1, 0}, dy4 = {0, 1, 0, -1};
vi dx8 = {1, 1, 1, 0, 0, -1, -1, -1}, dy8 = {1, 0, -1, 1, -1, 1, 0, -1};

bool solve()
{
    int H, W, c;
    cin >> H >> W >> c;
    if (H == 0)
        return false;
    vector<vector<int>> P(H, vector<int>(W));
    for (int i = 0; i < H; i++)
    {
        for (int j = 0; j < W; j++)
        {
            cin >> P[i][j];
        }
    }

    auto bfs = [&](vector<vector<int>> &F)
    {
        unordered_set<int> ret;
        queue<int> que;
        que.push(0);
        ret.insert(0);
        while (!que.empty())
        {
            int v = que.front();
            int x = v / W;
            int y = v % W;
            que.pop();
            for (int d = 0; d < 4; d++)
            {
                int nx = x + dx4[d], ny = y + dy4[d];
                if (nx < 0 || nx >= H || ny < 0 || ny >= W)
                {
                    continue;
                }
                if (F[x][y] != F[nx][ny])
                {
                    continue;
                }
                int idx = nx * W + ny;
                if (ret.count(idx))
                {
                    continue;
                }
                ret.insert(idx);
                que.push(idx);
            }
        }
        return ret;
    };

    int ans = 0;
    auto f = [&](auto f, int k, vector<vector<int>> &P)
    {
        if (k == 5)
        {
            auto se = bfs(P);
            if (P[0][0] == c)
                ans = max(ans, (int)se.size());

            return;
        }

        auto se = bfs(P);

        for (int col = 1; col < 7; col++)
        {
            vector<vector<int>> new_P = P;

            for (auto idx : se)
            {
                int i = idx / W;
                int j = idx % W;
                new_P[i][j] = col;
            }
            f(f, k + 1, new_P);
        }

        return;
    };

    f(f, 0, P);
    cout << ans << endl;
    return true;
}
int main()
{
    while (solve())
        ;
    return 0;
}
accuracy: 1
time_ms: 1880
memory_kb: 3180
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(a) a.begin(),a.end()
#define reps(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) reps(i, 0, n)
#define rreps(i, a, n) for (int i = (a); i > (int)(n); i--)
const long long mod = 1000000007;
const long long INF = 1e18;
ll myceil(ll a, ll b) {return (a+b-1)/b;}


int h,w,c;

vector<vector<int>> v(h,vector<int> (w));
vector<vector<int>> con;
vector<vector<int>> gp;
int ans;



void f(int tm, int col) {
    auto vv = v;
    auto cc = con;
    rep(i,h) {
        rep(j,w) {
            if (con[i][j]) {
                v[i][j] = col;
            }
            if (i != 0 && con[i-1][j] && v[i][j] == col) {
                con[i][j] = 1;
                for (auto x : gp[i*w+j]) {
                    con[x/w][x%w] = 1;
                }
            }
            if (j != 0 && con[i][j-1] && v[i][j] == col) {
                con[i][j] = 1;
                for (auto x : gp[i*w+j]) {
                    con[x/w][x%w] = 1;
                }
            }
            if (i != h-1 && con[i+1][j] && v[i][j] == col) {
                con[i][j] = 1;
                for (auto x : gp[i*w+j]) {
                    con[x/w][x%w] = 1;
                }
            }
            if (j != w-1 && con[i][j+1] && v[i][j] == col) {
                con[i][j] = 1;
                for (auto x : gp[i*w+j]) {
                    con[x/w][x%w] = 1;
                }
            }
        }
    }

    if (tm <= 3) {
        reps(i,1,7) f(tm+1,i);
    }
    else if (tm == 4) {
        f(tm+1,c);
    }
    else {
        int temp = 0;
        rep(i,h) {
            rep(j,w) {
                temp += con[i][j];
            }
        }
        ans = max(ans,temp);
    }

    v = vv;
    con = cc;

}




void solve() {
    ans = 0;
    v.resize(h);
    rep(i,h) v[i].resize(w);

    con.resize(h);
    rep(i,h) con[i].resize(w);  


    rep(i,h) {
        rep(j,w) {
            cin >> v[i][j];
            con[i][j] = 0;
        }
    }

    con[0][0] = 1;

    gp.resize(0);
    gp.resize(h*w);


    rep(i,h) {
        rep(j,w) {
            if (i != h-1) {
                if (v[i][j] == v[i+1][j]) {
                    for (auto x : gp[i*w+j]) {
                        gp[x].push_back((i+1)*w+j);
                        gp[(i+1)*w+j].push_back(x);
                    }

                    gp[i*w+j].push_back((i+1)*w+j);
                    gp[(i+1)*w+j].push_back(i*w+j);

                }
            }
            if (j != w-1) {
                if (v[i][j] == v[i][j+1]) {
                    for (auto x : gp[i*w+j]) {
                        gp[x].push_back(i*w+j+1);
                        gp[i*w+j+1].push_back(x);
                    }

                    gp[i*w+j].push_back(i*w+j+1);
                    gp[i*w+j+1].push_back(i*w+j);

                }
            }
        }
    }

    for (auto x : gp[0]) {
        con[x/w][x%w] = 1;
    }


    reps(i,1,7) {
        f(1,i);
    }

    cout << ans << endl;
    return;
}


int main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    while (cin >> h >> w >> c && h != 0) {
        solve();
    }


	return 0;
}
accuracy: 1
time_ms: 480
memory_kb: 3416
final_rank: 6

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }
vi dx = {1, 0, -1, 0}, dy = {0, 1, 0, -1};
int seen[8][8];
int h, w, c;
int P[8][8];
int ans = 0, turn = 1;

vc<pair<int, int>> search(){
    turn++;
    vc<pair<int, int>> ret;
    deque<pair<int, int>> q;
    q.push_back({0, 0});
    ret.push_back({0, 0});
    seen[0][0] = turn;
    while (!q.empty()){
        auto [i, j] = q.front(); q.pop_front();
        rep(k, 4){
            int ni = i + dx[k], nj = j + dy[k];
            if (inside(ni, nj, h, w) && seen[ni][nj] < turn && P[i][j] == P[ni][nj]){
                seen[ni][nj] = turn;
                ret.push_back({ni, nj});
                q.push_back({ni, nj});
            }
        }
    }
    return ret;
}

void f(int x){
    int last = P[0][0];
    vc<pair<int, int>> S = search();
    if (x == 4){
        for (auto [i, j] : S) P[i][j] = c;
        ans = max(ans, len(search()));
        for (auto [i, j] : S) P[i][j] = last;
        return;
    }
    srep(nc, 1, 7){
        for (auto [i, j] : S) P[i][j] = nc;
        f(x + 1);
    }
    for (auto [i, j] : S) P[i][j] = last;
}
void solve(){
    ans = 0;
    rep(i, h) rep(j, w) cin >> P[i][j];
    f(0);
    cout << ans << endl;
}
int main(){
    rep(i, 8) rep(j, 8) seen[i][j] = 0;
    while (true){
        cin >> h >> w >> c;
        if (h == 0) break;
        solve();
    }
}
accuracy: 1
time_ms: 150
memory_kb: 3328
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<long long, long long>;
#define rep(i, a, b) for(long long i = (a); i < (b); ++i)
#define rrep(i, a, b) for(long long i = (a); i >= (b); --i)
constexpr long long inf = 4e18;
struct SetupIO {
    SetupIO() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout << fixed << setprecision(30);
    }
} setup_io;
struct UnionFind {
    UnionFind(const int N)
        : n(N), data(N, -1) {}
    int merge(const int a, const int b) {
        assert(0 <= a and a < n);
        assert(0 <= b and b < n);
        int x = leader(a), y = leader(b);
        if(x == y) return x;
        if(-data[x] < -data[y]) swap(x, y);
        data[x] += data[y];
        data[y] = x;
        return x;
    }
    bool same(const int a, const int b) {
        assert(0 <= a and a < n);
        assert(0 <= b and b < n);
        return leader(a) == leader(b);
    }
    int leader(const int a) {
        assert(0 <= a and a < n);
        if(data[a] < 0) return a;
        return data[a] = leader(data[a]);
    }
    int size(const int a) {
        assert(0 <= a and a < n);
        return -data[leader(a)];
    }
    vector<vector<int>> groups() {
        vector<int> leader_buf(n), group_size(n);
        for(int i = 0; i < n; ++i) {
            leader_buf[i] = leader(i);
            ++group_size[leader_buf[i]];
        }
        vector<vector<int>> result(n);
        for(int i = 0; i < n; ++i) {
            result[i].reserve(group_size[i]);
        }
        for(int i = 0; i < n; ++i) {
            result[leader_buf[i]].push_back(i);
        }
        result.erase(remove_if(result.begin(), result.end(), [&](const vector<int>& v) { return v.empty(); }), result.end());
        return result;
    }

   private:
    int n;
    vector<int> data;
};
int main(void) {
    constexpr int di[4] = {1, 0, -1, 0}, dj[4] = {0, 1, 0, -1};
    while(1) {
        int h, w, c;
        cin >> h >> w >> c;
        if(h == 0 and w == 0 and c == 0) break;
        c--;
        vector<vector<int>> p(h, vector<int>(w));
        rep(i, 0, h) {
            rep(j, 0, w) {
                cin >> p[i][j];
                p[i][j]--;
            }
        }
        auto dfs = [&](auto& dfs, const vector<vector<int>>& col, int t) -> int {
            UnionFind uf(h * w);
            rep(i, 0, h) {
                rep(j, 0, w) {
                    rep(d, 0, 4) {
                        int ni = i + di[d], nj = j + dj[d];
                        if(0 <= ni and ni < h and 0 <= nj and nj < w and col[i][j] == col[ni][nj]) {
                            uf.merge(i * w + j, ni * w + nj);
                        }
                    }
                }
            }
            if(t == 0) {
                if(col[0][0] == c) return uf.size(0);
                return 0;
            }
            int res = 0;
            rep(k, 0, 6) {
                vector<vector<int>> nex = col;
                rep(i, 0, h) {
                    rep(j, 0, w) {
                        if(uf.same(i * w + j, 0)) {
                            nex[i][j] = k;
                        }
                    }
                }
                res = max(res, dfs(dfs, nex, t - 1));
            }
            return res;
        };
        cout << dfs(dfs, p, 5) << '\n';
    }
}
accuracy: 1
time_ms: 1590
memory_kb: 3492
final_rank: 14

code_snippet: #include <bits/stdc++.h>
    using namespace std;
    
    template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
    template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
    #define rep(i,n) for (int i = 0; i < (n); ++i)

    typedef long long ll;
    typedef unsigned long long ull;
    using P=pair<ll,ll>;
    using T=tuple<int,int,int>;
    const int INF=1001001001;
    const ll INFL=1e18;
    const int mod=998244353;
	
	int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
    bool solve(){
		int n,m,col;
		cin>>n>>m>>col;
		if(!n&&!m&&!col)return false;

		vector<vector<int>>p(n,vector<int>(m));
		rep(i,n){
			rep(j,m){
				cin>>p[i][j];
			}
		}

		auto paint=[&](int col,vector<vector<int>>& t){
			queue<P>q;
			q.push({0,0});
			vector<vector<int>>vis(n,vector<int>(m));
			vis[0][0]=1;
			int connect=t[0][0];
			t[0][0]=col;
			int cnt=0;
			while(q.size()){
				auto [i,j]=q.front();q.pop();
				cnt++;
				rep(k,4){
					int ni=i+dx[k],nj=j+dy[k];
					if(ni<0||ni>=n||nj<0||nj>=m)continue;
					if(t[ni][nj]==connect&&vis[ni][nj]==0){
						q.push({ni,nj});
						t[ni][nj]=col;
						vis[ni][nj]=1;
					}
				}
			}
			return cnt;
		};

		int ans=0;
		for(int a=1;a<=6;a++){
			for(int b=1;b<=6;b++){
				for(int c=1;c<=6;c++){
					for(int d=1;d<=6;d++){
						auto t=p;
						int cnt=paint(a,t);
						cnt=paint(b,t);
						cnt=paint(c,t);
						cnt=paint(d,t);
						cnt=paint(col,t);

						cnt=paint(t[0][0],t);
						chmax(ans,cnt);
					}
				}
			}
		}
		cout<<ans<<endl;
		return true;
    }

    int main(){
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);

		while(1){
			if(!solve())break;
		}
		
        return 0;
    }
accuracy: 1
time_ms: 510
memory_kb: 3456
final_rank: 9

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

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

int ANS;
queue<pair<int,int>> Q;
int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1};

void DFS(int H, int W, int C, vector<vector<int>> A, int X) {
    vector<vector<bool>> Flag(H,vector<bool>(W,false));
    Flag[0][0] = true;
    Q.push({0,0});
    while(!Q.empty()) {
        pair<int,int> P = Q.front();
        Q.pop();
        rep(i,0,4) {
            int NX = P.first + dx[i], NY = P.second + dy[i];
            if (NX < 0 || H <= NX || NY < 0 || W <= NY) continue;
            if (!Flag[NX][NY] && (A[NX][NY] == A[0][0])) {
                Flag[NX][NY] = true;
                Q.push({NX,NY});
            }
        }
    }
    if (X == 5) {
        if (A[0][0] != C) return;
        int COUNT = 0;
        rep(i,0,H) rep(j,0,W) if (Flag[i][j]) COUNT++;
        chmax(ANS, COUNT);
        return;
    }
    rep(i,1,7) {
        vector<vector<int>> B = A;
        rep(j,0,H) rep(k,0,W) if (Flag[j][k]) B[j][k] = i;
        DFS(H,W,C,B,X+1);
    }
    return;
}

int main() {
while(1) {
    int H, W, C;
    cin >> H >> W >> C;
    if (H == 0) return 0;
    vector<vector<int>> A(H,vector<int>(W));
    rep(i,0,H) rep(j,0,W) cin >> A[i][j];
    ANS = 0;
    DFS(H,W,C,A,0);
    cout << ANS << endl;
}
}
accuracy: 1
time_ms: 1790
memory_kb: 3528
final_rank: 17

code_snippet: #include <algorithm>
#include <cmath>
#include <functional>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#include <stdio.h>
#include <stdlib.h>

#include <bitset>
#include <queue>
#include <unordered_map>

#define ll long long
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define repl(i, l, n) for (int i = l; i < (int)(n); i++)
#define mod(a, b) (a % b + b) % b
int cmp(const void* x, const void* y) {
  if (*(int*)x > *(int*)y) {
    return 1;
  } else if (*(int*)x < *(int*)y) {
    return -1;
  } else {
    return 0;
  }
}
int* imalloc(int n) {
  int* ret = (int*)malloc(sizeof(int) * n);
  return ret;
}
// N の約数をすべて求める関数
vector<long long> calc_divisors(long long N) {
  vector<long long> res;
  for (long long i = 1; i * i <= N; ++i) {
    if (N % i != 0) continue;
    res.push_back(i);
    if (N / i != i) res.push_back(N / i);
  }
  sort(res.begin(), res.end());
  return res;
}
// カスタムハッシュ関数
struct pair_hash {
  template <class T1, class T2>
  std::size_t operator()(const std::pair<T1, T2>& pair) const {
    return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second);
  }
};
// ベクターと座標，tc色をcに塗りつぶして面積を返す関数
void paint(vector<vector<int> >* p, vector<vector<int> >* tmp, int h, int w,
           int i, int j, int c, int tc) {
  if (i != 0) {
    if ((p[0][i - 1][j] == tc) && tmp[0][i - 1][j] == 0) {
      p[0][i - 1][j] = c;
      tmp[0][i - 1][j] = 1;
      paint(p, tmp, h, w, i - 1, j, c, tc);
    }
  }
  if (j != 0) {
    if ((p[0][i][j - 1] == tc) && tmp[0][i][j - 1] == 0) {
      p[0][i][j - 1] = c;
      tmp[0][i][j - 1] = 1;
      paint(p, tmp, h, w, i, j - 1, c, tc);
    }
  }
  if (i != h - 1) {
    if ((p[0][i + 1][j] == tc) && tmp[0][i + 1][j] == 0) {
      p[0][i + 1][j] = c;
      tmp[0][i + 1][j] = 1;
      paint(p, tmp, h, w, i + 1, j, c, tc);
    }
  }
  if (j != w - 1) {
    if ((p[0][i][j + 1] == tc) && tmp[0][i][j + 1] == 0) {
      p[0][i][j + 1] = c;
      tmp[0][i][j + 1] = 1;
      paint(p, tmp, h, w, i, j + 1, c, tc);
    }
  }
}
int paintcount(vector<vector<int> >* p, vector<vector<int> >* tmp, int h, int w,
               int i, int j, int c) {
  if (tmp[0][i][j] == 0) tmp[0][i][j] = 1;
  int size = 1;
  if (i > 0) {
    if ((p[0][i - 1][j] == c) && tmp[0][i - 1][j] == 0) {
      tmp[0][i - 1][j] = 1;
      size += paintcount(p, tmp, h, w, i - 1, j, c);
    }
  }
  if (j > 0) {
    if ((p[0][i][j - 1] == c) && tmp[0][i][j - 1] == 0) {
      p[0][i][j - 1] = c;
      tmp[0][i][j - 1] = 1;
      size += paintcount(p, tmp, h, w, i, j - 1, c);
    }
  }
  if (i < h - 1) {
    if ((p[0][i + 1][j] == c) && tmp[0][i + 1][j] == 0) {
      p[0][i + 1][j] = c;
      tmp[0][i + 1][j] = 1;
      size += paintcount(p, tmp, h, w, i + 1, j, c);
    }
  }
  if (j < w - 1) {
    if ((p[0][i][j + 1] == c) && tmp[0][i][j + 1] == 0) {
      p[0][i][j + 1] = c;
      tmp[0][i][j + 1] = 1;
      size += paintcount(p, tmp, h, w, i, j + 1, c);
    }
  }
  return size;
}

int main() {
  while (1) {
    int h, w, c;
    int ret = 0;
    cin >> h >> w >> c;
    if (h == 0 && w == 0 && c == 0) return 0;
    vector<vector<int> > p = vector<vector<int> >(h, vector<int>(w, 0));
    vector<vector<int> > pcopy = vector<vector<int> >(h, vector<int>(w, 0));
    vector<vector<int> > tmp = vector<vector<int> >(h, vector<int>(w, 0));
    rep(i, h) {
      rep(j, w) { cin >> p[i][j]; }
    }
    // うるせえ！全探索しよう！！！
    int nowcolor;
    int nextcolor;
    rep(k, pow(6, 6)) {
      // int k = pow(6, 5) + pow(6, 4) * 2 + pow(6, 3) * 3 + pow(6, 2) * 4 +
      //         pow(6, 1) * 5;
      rep(i, h) {
        rep(j, w) { pcopy[i][j] = p[i][j]; }
      }
      nowcolor = pcopy[0][0];
      repl(j, 1, 5) {
        nextcolor = (k / (int)pow(6, j - 1)) % 6 + 1;
        paint(&pcopy, &tmp, h, w, 0, 0, nextcolor, nowcolor);
        nowcolor = nextcolor;
        rep(i, h) {
          rep(j, w) { tmp[i][j] = 0; }
        }
        // tmp = vector<vector<int> >(h, vector<int>(w, 0));
        // cout << endl << "itr" << j << endl;
        // rep(i, h) {
        //   rep(j, w) { cout << pcopy[i][j] << ' '; }
        //   cout << endl;
        // }
      }
      // cout << endl;
      nextcolor = c;
      paint(&pcopy, &tmp, h, w, 0, 0, nextcolor, nowcolor);
      nowcolor = nextcolor;
      rep(i, h) {
        rep(j, w) { tmp[i][j] = 0; }
      }
      int maxtmp = paintcount(&pcopy, &tmp, h, w, 0, 0, nowcolor);
      rep(i, h) {
        rep(j, w) { tmp[i][j] = 0; }
      }
      // cout << maxtmp << ' ';
      ret = max(maxtmp, ret);
    }

    cout << ret << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 5630
memory_kb: 3764
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ans = 0;
ll h,w,c;

template<typename TN>
void print2DVector(const std::vector<std::vector<TN>>& vec, bool debug=false) {

    for (const auto& row : vec) {
        for (const auto& elem : row) {
            std::cout << elem << ' ';
        }
        std::cout << '\n';
    }

    if (debug) {
        cout << "----------------------------------------------------debug----------------------------------------------------\n";
    }
}
int dx[4] = {1, 0, -1, 0}; int dy[4] = {0, 1, 0, -1};
ll bfs(vector<vector<ll>> &G,vector<vector<ll>> &seen, ll to_col) {
    ll from_col = G[0][0];

    queue<pair<ll, ll>> que;
    que.push({0,0});
    seen[0][0] = 1;
    G[0][0] = to_col;

    ll ct = 0;
    while (!que.empty()) {
        auto [x,y] = que.front();
        que.pop();

        for (ll i = 0; i < 4; ++i) {
            ll nx = x + dx[i];
            ll ny = y + dy[i];

            if (nx >= 0 && nx < h && ny < w && ny >= 0 && seen[nx][ny]!=1 && G[nx][ny]==from_col) {
                que.push({nx,ny});
                seen[nx][ny] = 1;
                G[nx][ny] = to_col;
            }
        }
        ++ct;
    }

    return ct;
}

void dfs(vector<vector<ll>> G, ll ct, ll now) {
    if (ct==6) {
        ct = 0;
        vector<vector<ll>> seen(h, vector<ll>(w,0));
        if (G[0][0] == c) ct = bfs(G,seen,-1);
        ans = max(ct,ans);
        return;
    }

    if (now != -1) {
        vector<vector<ll>> seen(h, vector<ll>(w,0));
        bfs(G,seen,now);
        // print2DVector(G,true);
    }

    for (ll i = 0; i < 6; ++i) {
        dfs(G,ct+1,i);
    }
}
void solve() {
    while (1 ) {
    // ll h,w,c;
    cin >> h >> w >> c;
    if (h==0) break;
    --c;
    ans = 0;
    vector<vector<ll>> G(h);
    for (ll i = 0; i < h; ++i) {
        for (ll j = 0; j < w; ++j) {
            ll tmp;
            cin >> tmp;
            --tmp;
            G[i].push_back(tmp);
        }
    }

    dfs(G,0,-1);
    cout << ans << endl;

    }
}

int main() {
    solve();
    return 0;
}
accuracy: 1
time_ms: 5640
memory_kb: 3372
final_rank: 18

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <set>

using namespace std;

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

int main() {
    while (true) {
        int H, W, C;
        cin >> H >> W >> C;
        if (H == 0 && W == 0 && C == 0)break;
        vector<vector<int>> P(H, vector<int>(W));
        for (int i = 0; i < H; i++)for (int j = 0; j < W; j++)cin >> P[i][j];
        int ans = 0;
        queue<pair<vector<vector<int>>, int>> Q;
        set<vector<vector<int>>> vis;
        Q.push({P, 0});
        vis.insert(P);
        while (!Q.empty()) {
            auto [grid, cnt] = Q.front();Q.pop();
            if (cnt >= 5)continue;
            for (int col = 1; col <= 6; col++) {
                auto next_grid = grid;
                int prev_col = grid[0][0];
                next_grid[0][0] = col;
                queue<pair<int, int>> q;
                vector<vector<bool>> used(H, vector<bool>(W, false));
                q.push({0, 0});
                used[0][0] = true;
                while (!q.empty()) {
                    auto [x, y] = q.front();q.pop();
                    for (int i = 0; i < 4; i++) {
                        int nx = x + dx[i], ny = y + dy[i];
                        if (!(0 <= nx && nx < H && 0 <= ny && ny < W) || used[nx][ny])continue;
                        if (next_grid[nx][ny] == prev_col) {
                            next_grid[nx][ny] = col;
                            used[nx][ny] = true;
                            q.push({nx, ny});
                        }
                    }
                }
                if (!vis.count(next_grid)) {
                    vis.insert(next_grid);
                    Q.push({next_grid, cnt + 1});
                }
                int res = 0;
                for(int i = 0;i < H;i++)for(int j = 0;j < W;j++)used[i][j] = false;
                q.push({0, 0});
                used[0][0] = true;
                while (!q.empty()) {
                    auto [x, y] = q.front();q.pop();
                    res++;
                    for (int i = 0; i < 4; i++) {
                        int nx = x + dx[i], ny = y + dy[i];
                        if (!(0 <= nx && nx < H && 0 <= ny && ny < W) || used[nx][ny])continue;
                        if (next_grid[nx][ny] == col) {
                            used[nx][ny] = true;
                            q.push({nx, ny});
                        }
                    }
                }
                if (col == C)ans = max(ans, res);
            }
        }
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 200
memory_kb: 3932
final_rank: 8

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <set>

using namespace std;

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

int main() {
    while (true) {
        int H, W, C;
        cin >> H >> W >> C;
        if (H == 0 && W == 0 && C == 0)break;
        vector<vector<int>> P(H, vector<int>(W));
        for (int i = 0; i < H; i++)for (int j = 0; j < W; j++)cin >> P[i][j];
        int ans = 0;
        queue<pair<vector<vector<int>>, int>> Q;
        set<vector<vector<int>>> vis;
        Q.push({P, 0});
        vis.insert(P);
        while (!Q.empty()) {
            auto [grid, cnt] = Q.front();Q.pop();
            if (cnt >= 5)continue;
            for (int col = 1; col <= 6; col++) {
                auto next_grid = grid;
                int prev_col = grid[0][0];
                next_grid[0][0] = col;
                queue<pair<int, int>> q;
                vector<vector<bool>> used(H, vector<bool>(W, false));
                q.push({0, 0});
                used[0][0] = true;
                while (!q.empty()) {
                    auto [x, y] = q.front();q.pop();
                    for (int i = 0; i < 4; i++) {
                        int nx = x + dx[i], ny = y + dy[i];
                        if (!(0 <= nx && nx < H && 0 <= ny && ny < W) || used[nx][ny])continue;
                        if (next_grid[nx][ny] == prev_col) {
                            next_grid[nx][ny] = col;
                            used[nx][ny] = true;
                            q.push({nx, ny});
                        }
                    }
                }
                if (!vis.count(next_grid)) {
                    vis.insert(next_grid);
                    Q.push({next_grid, cnt + 1});
                }
                int res = 0;
                for(int i = 0;i < H;i++)for(int j = 0;j < W;j++)used[i][j] = false;
                q.push({0, 0});
                used[0][0] = true;
                while (!q.empty()) {
                    auto [x, y] = q.front();q.pop();
                    res++;
                    for (int i = 0; i < 4; i++) {
                        int nx = x + dx[i], ny = y + dy[i];
                        if (!(0 <= nx && nx < H && 0 <= ny && ny < W) || used[nx][ny])continue;
                        if (next_grid[nx][ny] == col) {
                            used[nx][ny] = true;
                            q.push({nx, ny});
                        }
                    }
                }
                if (col == C)ans = max(ans, res);
            }
        }
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 200
memory_kb: 4312
final_rank: 12

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <map>
#include <cmath>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using ll = long long;


/*
幅優先探索(bfs)
1.左上の色を変更する
2.変える前の色と同じ色も同じく変更する
3.そのパネルの大きさと最大値を比べて更新する
*/

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

int main() {
    while (true) {
        int H, W, C;
        cin >> H >> W >> C;
        if (H == 0 && W == 0 && C == 0)break;
        vector<vector<int>> P(H, vector<int>(W));
        for (int i = 0; i < H; i++)for (int j = 0; j < W; j++)cin >> P[i][j];

        int ans = 0;
        queue<pair<vector<vector<int>>, int>> Q;
        set<vector<vector<int>>> vis;
        Q.push({P, 0});
        vis.insert(P);
        while (!Q.empty()) {
            auto [grid, cnt] = Q.front();Q.pop();
            if (cnt >= 5)continue;
            for (int col = 1; col <= 6; col++) {
                // 左上の色を変更する
                auto next_grid = grid;
                int prev_col = grid[0][0];
                next_grid[0][0] = col;

                // 変える前の色と同じ色も同じく変更する
                queue<pair<int, int>> q;
                vector<vector<bool>> used(H, vector<bool>(W, false));
                q.push({0, 0});
                used[0][0] = true;
                while (!q.empty()) {
                    auto [x, y] = q.front();q.pop();
                    for (int i = 0; i < 4; i++) {
                        int nx = x + dx[i], ny = y + dy[i];
                        if (!(0 <= nx && nx < H && 0 <= ny && ny < W) || used[nx][ny])continue;
                        if (next_grid[nx][ny] == prev_col) {
                            next_grid[nx][ny] = col;
                            used[nx][ny] = true;
                            q.push({nx, ny});
                        }
                    }
                }
                if (!vis.count(next_grid)) {
                    vis.insert(next_grid);
                    Q.push({next_grid, cnt + 1});
                }
                
                // そのパネルの大きさと最大値を比べて更新する
                int res = 0;
                for(int i = 0;i < H;i++)for(int j = 0;j < W;j++)used[i][j] = false;
                q.push({0, 0});
                used[0][0] = true;
                while (!q.empty()) {
                    auto [x, y] = q.front();q.pop();
                    res++;
                    for (int i = 0; i < 4; i++) {
                        int nx = x + dx[i], ny = y + dy[i];
                        if (!(0 <= nx && nx < H && 0 <= ny && ny < W) || used[nx][ny])continue;
                        if (next_grid[nx][ny] == col) {
                            used[nx][ny] = true;
                            q.push({nx, ny});
                        }
                    }
                }
                if (col == C)ans = max(ans, res);
            }
        }
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 200
memory_kb: 4176
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <map>
#include <cmath>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using ll = long long;


/*
幅優先探索(bfs)
1.左上の色を変更する
2.変える前の色と同じ色も同じく変更する
3.そのパネルの大きさと最大値を比べて更新する
*/

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

int main() {
    while (true) {
        int H, W, C;
        cin >> H >> W >> C;
        if (H == 0 && W == 0 && C == 0)break;
        vector<vector<int>> P(H, vector<int>(W));
        for (int i = 0; i < H; i++)for (int j = 0; j < W; j++)cin >> P[i][j];

        int ans = 0;
        queue<pair<vector<vector<int>>, int>> Q;
        set<vector<vector<int>>> vis;
        Q.push({P, 0});
        vis.insert(P);
        while (!Q.empty()) {
            auto [grid, cnt] = Q.front();Q.pop();
            if (cnt >= 5)continue;
            for (int col = 1; col <= 6; col++) {
                // 左上の色を変更する
                auto next_grid = grid;
                int prev_col = grid[0][0];
                next_grid[0][0] = col;

                // 変える前の色と同じ色も同じく変更する
                queue<pair<int, int>> q;
                vector<vector<bool>> used(H, vector<bool>(W, false));
                q.push({0, 0});
                used[0][0] = true;
                while (!q.empty()) {
                    auto [x, y] = q.front();q.pop();
                    for (int i = 0; i < 4; i++) {
                        int nx = x + dx[i], ny = y + dy[i];
                        if (!(0 <= nx && nx < H && 0 <= ny && ny < W) || used[nx][ny])continue;
                        if (next_grid[nx][ny] == prev_col) {
                            next_grid[nx][ny] = col;
                            used[nx][ny] = true;
                            q.push({nx, ny});
                        }
                    }
                }
                if (!vis.count(next_grid)) {
                    vis.insert(next_grid);
                    Q.push({next_grid, cnt + 1});
                }

                int res = 0;
                for(int i = 0;i < H;i++)for(int j = 0;j < W;j++)used[i][j] = false;
                q.push({0, 0});
                used[0][0] = true;
                while (!q.empty()) {
                    auto [x, y] = q.front();q.pop();
                    res++;
                    for (int i = 0; i < 4; i++) {
                        int nx = x + dx[i], ny = y + dy[i];
                        if (!(0 <= nx && nx < H && 0 <= ny && ny < W) || used[nx][ny])continue;
                        if (next_grid[nx][ny] == col) {
                            used[nx][ny] = true;
                            q.push({nx, ny});
                        }
                    }
                }
                // そのパネルの大きさと最大値を比べて更新する
                if (col == C)ans = max(ans, res);
            }
        }
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 200
memory_kb: 4308
final_rank: 11

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <stack>
#include <cassert>
using namespace std;

struct d{
  int y,x;
};

stack<d> loc;

void change(vector<vector<int>> &A, int i, int j, int h, int w, int col, int prev){
  if(i > 0 && A[i-1][j] == prev){
    A[i-1][j] = col;
    loc.push({i-1,j});
    change(A, i-1, j, h, w, col, prev);
  }
  if(j > 0 && A[i][j-1] == prev){
    A[i][j-1] = col;
    loc.push({i,j-1});
    change(A, i, j-1, h, w, col, prev);
  }
  if(i+1 < h && A[i+1][j] == prev){
    A[i+1][j] = col;
    loc.push({i+1,j});
    change(A, i+1, j, h, w, col, prev);
  }
  if(j+1 < w && A[i][j+1] == prev){
    A[i][j+1] = col;
    loc.push({i,j+1});
    change(A, i, j+1, h, w, col, prev);
  }
}

int val(vector<vector<int>> &A, int i, int j, int h, int w, int col){
  int ret = 0;
  if(i > 0 && A[i-1][j] == col){
    A[i-1][j] = -1;
    ret += val(A, i-1, j, h, w, col);
  }
  if(j > 0 && A[i][j-1] == col){
    A[i][j-1] = -1;
    ret += val(A, i, j-1, h, w, col);
  }
  if(i+1 < h && A[i+1][j] == col){
    A[i+1][j] = -1;
    ret += val(A, i+1, j, h, w, col);
  }
  if(j+1 < w && A[i][j+1] == col){
    A[i][j+1] = -1;
    ret += val(A, i, j+1, h, w, col);
  }
  return ret+1;
}

int ans = 0;



void dfs(vector<vector<int>>& A, int count, int prev, int h, int w, int c){
  if(count == 5){
    int value = A[0][0];
    A[0][0] = -1;
    int x = val(A, 0, 0, h, w, value);
    ans = max(ans, x);

    for(int i = 0; h > i; i++){
      for(int j = 0; w > j; j++){
        if(A[i][j] == -1){
          A[i][j] = value;
        }
      }
    }
    return;
  }
  auto B = A;
  for(int i = 1; 6 >= i; i++){
    if(prev == i)continue;
    if(count == 4 && c != i)continue;
    int val = A[0][0];
    //cout << "?" << count << " " << prev << " " << i << " " << val << endl;
    loc.push({-1,-1});
    loc.push({0,0});
    A[0][0] = i;
    change(A, 0, 0, h, w, i, val);
    //for(int j = 0; h > j; j++){
    //  for(int k = 0; w > k; k++){
    //    cout << A[j][k] << " ";
    //  }
    //  cout << endl;
    //}
    //cout << "!" << count << " " << prev << " " << i << endl;
    dfs(A, count+1, i, h, w, c);
    while(loc.size()){
      auto z = loc.top();loc.pop();
      if(z.y == -1)break;
      A[z.y][z.x] = prev;
      //cout << z.y << " " << z.x << endl;
    }
    assert(A[0][0] == prev);
  }
}

void solve(int h, int w, int c){
  ans = 0;
  vector<vector<int>> A(h, vector<int>(w));
  for(int i = 0; h > i; i++){
    for(int j = 0; w > j; j++){
      cin>>A[i][j];
    }
  }
  dfs(A, 0, A[0][0], h, w, c);
  cout << ans << endl;
}

int main(){
  int h,w,c;
  while(cin>>h>>w>>c){
    if(h == 0)return 0;
    solve(h,w,c);
  }
}
accuracy: 1
time_ms: 70
memory_kb: 3380
final_rank: 2

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0; i< (n); i++)
#define mkp(i,j) make_pair((i),(j))
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int mod = 998244353;
const int inf = (1<<30);
class DisjointSetUnion {
  int n;
  vector<int> vals;

  public:
    DisjointSetUnion() = default;
    explicit DisjointSetUnion(int n) : n(n), vals(n,-1){}


    int leader(int v){
      assert(v < n);
      if(vals[v] < 0) return v;
      return vals[v] = leader(vals[v]);
    }

    bool same(int u, int v){
      assert(v < n);
      assert(u < n);
      return leader(u) == leader(v);
    }


    int merge(int u, int v){
      assert(u < n);
      assert(v < n);

      int x = leader(u);
      int y = leader(v);

      if(x == y) return x;
      if(-vals[x] < -vals[y]) swap(x,y);
      vals[x] += vals[y];
      vals[y] = x;
      return x;
    }
    // === no need to implement from here ===


    int group_size(int v){
      assert(v < n);
      return -vals[leader(v)];
    }

    vector<vector<int>> groups() {
      vector<vector<int>> result(n);
      vector<int> leaders(n), g_size(n);

      for(int v = 0; v<n; v++){
        leaders[v] = leader(v);
        g_size[leaders[v]]++;
      }
      for(int v = 0; v < n; v++){
        result[v].reserve(g_size[v]);
      }
      for(int v = 0; v  < n; v++){
        result[leaders[v]].emplace_back(v);
      }
      auto empty_check = [](const vector<int> &vs){
        return vs.empty();
      };
      result.erase(
      remove_if(result.begin(), result.end(), empty_check),
      result.end());

      return result;
    }
};

int check(vector<int> &q, vector<vector<int>> &p){
	int h = p.size();
	int w = p[0].size();
	DisjointSetUnion uni(h*w); // uni( i*w + j)
	rep(i,h) rep(j,w){
		if(i != h-1 && p[i][j] == p[i+1][j]) uni.merge(i*w + j , (i+1)*w + j);
		if(j != w-1 &&  p[i][j] == p[i][j+1]) uni.merge(i*w + j , (i)*w + j+1);
	}
	int vx[4] = {1,-1,0,0};
	int vy[4] = {0,0,1,-1};
	rep(k,5){
		int mc = q[k];
		rep(i,h){
			rep(j,w){
				if(!(uni.same(0,i*w+j))) continue;
				rep(l,4){
					int ny = i + vy[l];
					int nx = j + vx[l];
					if( ny < 0 || ny >= h || nx < 0 || nx >= w || p[ny][nx] != mc) continue;
					uni.merge(0,ny*w + nx);
				}
			}
		}
	}
	/*
	if(q[0] == 2 && q[1] == 3 && q[2] == 2 && q[3] == 5){
		cout<<"output"<<endl;
		auto res = uni.groups();
		for(auto x : res){
			for(auto y : x) cout<<y<<" ";
			cout<<endl;
		}
		cout<<"end"<<endl;
	}*/
			
	return uni.group_size(0);
}





int dfs(int i,int c,vector<int> &q, vector<vector<int>> &p){
	if( i == 4){
		q[i] = c;
		//rep(j,5) cout<<q[j]<<" ";
		//cout<<endl;

		return check(q,p);
	}
	int res = 0;
	rep(j,6){
		q[i] = j+1;
		res = max(res,dfs(i+1,c,q,p));
	}
	return res;
}
		

		


int main(){
	while(1){
		int h,w,c; cin>>h>>w>>c;
		if(h == 0) break;
		vector<vector<int>> p(h,vector<int>(w));
		rep(i,h) rep(j,w) cin>>p[i][j];
		vector<int> q(5);
		cout<<dfs(0,c,q,p)<<endl;
	}

}
accuracy: 1
time_ms: 300
memory_kb: 3320
final_rank: 5

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

int main(){
    while(1){
        int H, W, COLOR; cin >> H >> W >> COLOR;
        if(H == 0 && W == 0 && COLOR == 0) break;

        vector<vector<int>> P(H, vector<int>(W));
        for(int i = 0; i < H; i++){
            for(int j = 0; j < W; j++){
                cin >> P[i][j];
            }
        }

        const int dr[4] = {0, 1, 0, -1};
        const int dc[4] = {1, 0, -1, 0};
        auto cnt = [&](vector<vector<int>> &G, int col) -> int {
            queue<pair<int, int>> que;
            vector<vector<bool>> used(H, vector<bool>(W));
            int pre = G[0][0];
            que.push(make_pair(0, 0));
            used[0][0] = 1;
            int res = 0;

            while(!que.empty()){
                auto [r, c] = que.front();
                que.pop();
                //cout << r << " " << c << endl;
                res++;
                G[r][c] = col;
                for(int i = 0; i < 4; i++){
                    int nr = r + dr[i], nc = c + dc[i];
                    if(nr < 0 || H <= nr || nc < 0 || W <= nc) continue;
                    if(G[nr][nc] == pre && !used[nr][nc]){
                        used[nr][nc] = 1;
                        que.push(make_pair(nr, nc));
                    }
                }
            }
            return res;
        };
    
        auto dfs = [&](auto f, vector<vector<int>> G, int col, int dep) -> int {
            // connect. change col
            int res = cnt(G, col);
            if(dep == 5) return cnt(G, col);
            // join
            for(int i = 1; i <= 6; i++){
                if(dep == 4 && i != COLOR) continue;
                if(i == col) continue;
                res = max(res, f(f, G, i, dep + 1));
            }
            return res;
        };

        cout << dfs(dfs, P, P[0][0], 0) << endl;
    }
}
accuracy: 1
time_ms: 240
memory_kb: 3316
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
template<int mod>istream &operator>>(istream &is,static_modint<mod> &a){long long b;is>>b;a=b;return is;}
istream &operator>>(istream &is,modint &a){long long b;cin>>b;a=b;return is;}
#endif
#ifdef LOCAL
#include "debug.h"
#else
#define debug(...) static_cast<void>(0)
#define debugg(...) static_cast<void>(0)
#define esper(...) static_cast<void>(0)
template<typename T1,typename T2>ostream &operator<<(ostream &os,const pair<T1,T2>&p){os<<p.first<<' '<<p.second;return os;}
#endif
using ll=long long;
using ull=unsigned long long;
using P=pair<ll,ll>;
template<typename T>using minque=priority_queue<T,vector<T>,greater<T>>;
template<typename T>bool chmax(T &a,const T &b){return (a<b?(a=b,true):false);}
template<typename T>bool chmin(T &a,const T &b){return (a>b?(a=b,true):false);}
template<typename T1,typename T2>istream &operator>>(istream &is,pair<T1,T2>&p){is>>p.first>>p.second;return is;}
template<typename T>istream &operator>>(istream &is,vector<T> &a){for(auto &i:a)is>>i;return is;}
template<typename T1,typename T2>void operator++(pair<T1,T2>&a,int n){a.first++,a.second++;}
template<typename T1,typename T2>void operator--(pair<T1,T2>&a,int n){a.first--,a.second--;}
template<typename T>void operator++(vector<T>&a,int n){for(auto &i:a)i++;}
template<typename T>void operator--(vector<T>&a,int n){for(auto &i:a)i--;}
#define reps(i,a,n) for(int i=(a);i<(n);i++)
#define rep(i,n) reps(i,0,n)
#define all(x) x.begin(),x.end()
#define pcnt(x) __builtin_popcountll(x)
#define fin(x) return cout<<x<<'\n',static_cast<void>(0)
ll myceil(ll a,ll b){return (a+b-1)/b;}
template<typename T,size_t n,size_t id=0>
auto vec(const int (&d)[n],const T &init=T()){
  if constexpr (id<n)return vector(d[id],vec<T,n,id+1>(d,init));
  else return init;
}
void SOLVE();
int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout<<fixed<<setprecision(16);
  #ifdef LOCAL
  clock_t start=clock();
  #endif
  int testcase=1;
  //cin>>testcase;
  for(int i=0;i<testcase;i++){
    SOLVE();
  }
  #ifdef LOCAL
  cerr<<"time:";
  cerr<<(clock()-start)/1000;
  cerr<<"ms\n";
  #endif
}
int h,w;
inline bool inarea(int x,int y){
  return 0<=x&&0<=y&&x<h&&y<w;
}
vector<pair<int,int>>around(int x,int y){
  vector<pair<int,int>>ret;
  vector<int>dx{1,0,-1,0},dy{0,1,0,-1};
  rep(i,4){
    int cx=x+dx[i],cy=y+dy[i];
    if(inarea(cx,cy))ret.emplace_back(cx,cy);
  }
  return ret;
}
vector<pair<int,int>>around8(int x,int y){
  vector<pair<int,int>>ret;
  vector<int>dx{1,1,0,-1,-1,-1,0,1},dy{0,1,1,1,0,-1,-1,-1};
  rep(i,8){
    int cx=x+dx[i],cy=y+dy[i];
    if(inarea(cx,cy))ret.emplace_back(cx,cy);
  }
  return ret;
}
void SOLVE(){
  while(true){
    int c;
    cin>>h>>w>>c;
    if(h+w+c==0)break;
    vector<vector<int>>a(h,vector<int>(w));
    cin>>a;
    a--,c--;
    int ans=0;
    rep(i,6){
      rep(j,6)if(i!=j){
        rep(k,6)if(j!=k){
          rep(l,6)if(k!=l){
            auto b(a);
            vector<int>step{i,j,k,l,c};
            for(auto col:step){
              queue<pair<int,int>>que;
              que.push({0,0});
              int pre=b[0][0];
              b[0][0]=col;
              vector<vector<bool>>seen(h,vector<bool>(w,false));
              seen[0][0]=true;
              while(!que.empty()){
                auto [x,y]=que.front();
                que.pop();
                for(auto [nx,ny]:around(x,y))if(!seen[nx][ny]&&b[nx][ny]==pre){
                  seen[nx][ny]=true;
                  b[nx][ny]=col;
                  que.push({nx,ny});
                }
              }
            }
            assert(b[0][0]==c);
            int sum=0;
            vector<vector<bool>>s(h,vector<bool>(w,false));
            s[0][0]=true;
            queue<pair<int,int>>que;
            que.push({0,0});
            while(!que.empty()){
              auto [x,y]=que.front();que.pop();
              for(auto [nx,ny]:around(x,y))if(!s[nx][ny]&&b[x][y]==b[nx][ny])s[nx][ny]=true,que.push({nx,ny});
            }
            rep(i,h)rep(j,w)sum+=s[i][j];
            chmax(ans,sum);
          }
        }
      }
    }
    cout<<ans<<endl;
  }
}
accuracy: 1
time_ms: 890
memory_kb: 3468
final_rank: 13