//배양액이 동시에 떨어지는 곳에 꽃이 피어남
//황토색 땅이 5곳 이라면 
// 배양액이 2개, 2개다? 
//0은 호수, 1은 배양액을 뿌릴 수 없는 땅, 2는 배양액을 뿌릴 수 있는 땅
#include <iostream>
#include <queue>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
int dir[4][2] = { {1,0}, { 0,1 }, { -1,0 }, { 0,-1 } };
//n,m,G,R
int n, m, G, R;
int map[51][51];
int svisit[11];
int ans;
typedef struct xy {
	int x, y;
};
typedef struct info {
	int TIME;// 배양액이 뿌려진 시점
	int color;// 뿌려진 배양액의 색
	bool flower;// 꽃이 피어진 자리인가
};

info visit[51][51];
vector <xy> save;//배양액을 뿌릴 수 있는 땅에 대한 좌표
int savesz;

int bfs() {
	memset(visit, 0, sizeof(visit));
	int TIME = 1;
	queue<xy> greenq;
	queue<xy> redq;
	int ret = 0;// 꽃의 갯수
	for (int i = 0; i < savesz; i++) {
		//cout << svisit[i] << " ";//
		if (svisit[i] == 1) {//green
			int x = save[i].x,y= save[i].y;
			greenq.push({ x,y });
			visit[x][y] = {TIME,1,0};
		}
		else if (svisit[i] == 2) {
			int x = save[i].x, y = save[i].y;
			redq.push({ x,y });
			visit[x][y] = {TIME,2,0};
		}
	}
	//cout << endl;//
	//초기 배양액 위치 
	//for (int i = 0; i < n; i++) {
	//	for (int j = 0; j < m; j++) {
	//		cout << visit[i][j].color << " ";
	//	}cout << endl;
	//}cout << endl;

	while (!(greenq.size()==0 && redq.size()==0)) {
		int sz = greenq.size();
		TIME++;
		while (sz--) {//green먼저 땅 넓히기
			int fx = greenq.front().x, fy = greenq.front().y;
			greenq.pop();
			if (visit[fx][fy].color == 5)continue;
			for (int d = 0; d < 4; d++) {
				int nx = fx + dir[d][0], ny = fy + dir[d][1];
				if (nx < 0 || ny < 0 || nx >= n || ny >= m)continue;
				if (!map[nx][ny])continue;
				if (visit[nx][ny].color == 0) {
					visit[nx][ny] = { TIME,1,0 };
					greenq.push({ nx,ny });
				}
				
			}
		}

		sz = redq.size();
		while (sz--) {
			int fx = redq.front().x, fy = redq.front().y;
			redq.pop();

			for (int d = 0; d < 4; d++) {
				int nx = fx + dir[d][0], ny = fy + dir[d][1];
				if (nx < 0 || ny < 0 || nx >= n || ny >= m)continue;
				if (!map[nx][ny])continue;
				if (!visit[nx][ny].flower && visit[nx][ny].color == 1 && visit[nx][ny].TIME == TIME) {
					ret++;
					visit[nx][ny].flower = true;
					visit[nx][ny].color = 5;
					continue;
				}
				if (visit[nx][ny].color)continue;
				visit[nx][ny].TIME = TIME;
				visit[nx][ny].color = 2;
				redq.push({ nx,ny });
			}
		}


	}

	//동시에 ! 같은 곳을 가면 꽃이 핌
	//if (ret == 6) {
	//	cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
	//	for (int i = 0; i < n; i++) {
	//		for (int j = 0; j < m; j++) {
	//			cout << visit[i][j].color << " ";
	//		}cout << endl;
	//	}
	//}

	

	return ret;
}

void dfs(int num,int cnt,int gcnt,int rcnt) {
	//배양액 넣을건데..배양액 갯수 중에서 R+G개 만큼 뽑고
	//svisit에 1,2로 어디에 어떤거 줄건지 구분
	//cout << "num " << num << " cnt " << cnt << " gcnt " << gcnt << " rcnt " << rcnt << endl;
	if (rcnt+gcnt == G + R) {
		int ret=bfs();
		ans = max(ans, ret);
		return;
	}

	for (int i = num; i < savesz; i++) {
		if (svisit[i])continue;
		if (gcnt < G) {
			svisit[i] = 1;
			dfs(i, cnt + 1, gcnt + 1, rcnt);
			svisit[i] = false;
		}
		if (rcnt < R) {
			svisit[i] = 2;
			dfs(i, cnt + 1, gcnt, rcnt + 1);
			svisit[i] = false;
		}
	}

}

void Input() {
	cin >> n >> m >> G >> R;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> map[i][j];
			if (map[i][j] == 2) {
				save.push_back({ i,j });
			}
		}
	}
	savesz = save.size();
}

int main() {
	cin.tie(0);
	cin.sync_with_stdio(0);
	Input();
	dfs(0, 0, 0, 0);
	cout << ans << endl;
}