#pragma warning(disable:4996)
#include <iostream>
#include <cstdio>
#include <queue>
#include <cmath>
#include <cstring>
using namespace std;
int map[51][51]; // 인구맵
int c_union[51][51]; // 현재 연합
int p_union[51][51]; // 이전 연합
int dx[] = { -1,1,0,0 }; // 이동 방향
int dy[] = { 0,0,-1,1 };
// worst case 기준으로 배열 선언
int union_members[51 * 51]; // 해당 연합의 인원수
int union_cnts[51 * 51]; // 해당 연합의 국가수
bool open_wall(int cx, int cy, int nx, int ny, int L, int R)
{ // 조건을 만족하면 국경을 연다.
int diff = abs(map[cy][cx] - map[ny][nx]);
if (L <= diff && diff <= R) return true;
else return false;
}
int main()
{
int N, L, R;
scanf("%d %d %d", &N, &L, &R);
for (int j = 0; j < N; j++)
{
for (int i = 0; i < N; i++)
{
scanf("%d", &map[j][i]);
}
}
int move = 0;
while (1)
{
//연합을 나누고
int union_cnt = 1;
for (int j = 0; j < N; j++)
{
for (int i = 0; i < N; i++)
{
//모든 국가 중 union이 구분되었다면 넘어간다.
if (c_union[j][i] != 0) continue;
queue <pair<int, int>> q;
c_union[j][i] = union_cnt;
q.push(make_pair(i, j));
while (!q.empty())
{
int cx = q.front().first;
int cy = q.front().second;
q.pop();
for (int k = 0; k < 4; k++)
{
int nx = cx + dx[k];
int ny = cy + dy[k];
// 다음 국가 선택 범위 벗어나면 넘어간다.
if (nx < 0 || N <= nx || ny < 0 || N <= ny) continue;
// 다음 국가가 분류 되어있다면 넘어간다.
if (c_union[ny][nx] != 0) continue;
//만약 벽을 열 수 있다면
if (open_wall(cx, cy, nx, ny, L, R))
{
c_union[ny][nx] = union_cnt; // 같은 연합으로.
q.push(make_pair(nx, ny));
}
}
}
union_cnt++; // 현재 연결된 모든 연합을 찾아 연결했으므로 다음으로 넘어간다.
}
}
//연합을 비교해서 이전 연합과 같으면 종료
int temp = 0;
for (int j = 0; j < N; j++)
{
for (int i = 0; i < N; i++)
{
if (c_union[j][i] == p_union[j][i]) temp++;
}
}
if (temp == N * N) break;
//나눠진 연합 내에서 인구수 구한담에
for (int j = 0; j < N; j++)
{
for (int i = 0; i < N; i++)
{
union_members[c_union[j][i]] += map[j][i]; // 해당 국가의 연합에 인원수 더하고
union_cnts[c_union[j][i]]++; // 해당 union 인원수 계산
}
}
//평균 인원수 구하고
for (int i = 0; i < N*N; i++)
{
//만약 인원 없는 연합이라면 넘어간다.
if (union_members[i] == 0) continue;
union_members[i] = int(union_members[i] / union_cnts[i]);
}
//map에서 인구이동
for (int j = 0; j < N; j++)
{
for (int i = 0; i < N; i++)
{
map[j][i] = union_members[c_union[j][i]]; // 인구 이동
p_union[j][i] = c_union[j][i]; // 비교를 위해 이전 연합 저장
c_union[j][i] = 0; // c_union 초기화
}
}
move++; // 인구 이동 횟수 센다.
//변수 초기화
memset(union_members, 0, sizeof(union_members));
memset(union_cnts, 0, sizeof(union_cnts));
}
printf("%d\n", move - 1); // while문의 중간에 현재 연합을 구하고 비교해 빠져나오므로 1을 뺀 값이 정답이 된다.
//std::system("pause");
return 0;
}