import java.io.*;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static int[][] graph = new int[501][501];
static boolean[][] visited = new boolean[501][501];
static int[] dx = {0, 0, -1, 1}; // 상,하,좌,우
static int[] dy = {1, -1, 0, 0};
static Queue<Node> queue = new LinkedList<>();
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer st;
public static void main(String[] args) throws IOException {
st = new StringTokenizer(br.readLine(), " ");
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine()," ");
for (int j = 0; j < m; j++) {
graph[i][j] = Integer.parseInt(st.nextToken());
}
}
int count = 0;
int maxSize = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (graph[i][j] == 0 || visited[i][j]) continue;
count++;
visited[i][j] = true;
queue.add(new Node(i, j));
int area = 0;
while (!queue.isEmpty()) {
area++;
Node cur = queue.poll();
for (int dir = 0; dir < 4; dir++) {
int x = cur.getX() + dx[dir];
int y = cur.getY() + dy[dir];
if (x < 0 || x >= n || y < 0 || y >= m) continue;
if (graph[x][y] != 1 || visited[x][y]) continue;
visited[x][y] = true;
queue.add(new Node(x, y));
}
}
maxSize = Math.max(maxSize, area);
}
}
System.out.println(count);
System.out.println(maxSize);
}
static class Node {
private int x;
private int y;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
}
// 후기...
1260번: DFS와 BFS 문제는 단순 구현 문제인데, 예전에 이 문제 푼 이후로 그래프 탐색을 활용하는 문제를 풀어보질 않은데다, 자다가 누가 툭 건드려서 bfs를 어떻게 구현하는지 물어보면 바로 투두두둑 짤 수 있을 정도로 기억하고 있질 않아서 그런지 오늘 하루 bfs를 일일이 생각하며 구현하느라 조금 애먹었다...
이거 때문에 bfs 뼈대 자체는 제대로 머릿속에 들어온 것 같다.
이래서 PS는 왠만하면 유형별로 매일 조금씩 풀어야 하나 싶다...