import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.ArrayDeque;
import java.util.Queue;

public class nC {

	static class Scanner {
		StreamTokenizer in;

		Scanner(InputStream is) {
			in = new StreamTokenizer(new InputStreamReader(is));
			in.resetSyntax();
			in.whitespaceChars(0, 32);
			in.wordChars(33, 255);
		}

		String next() {
			try {
				in.nextToken();
				return in.sval;
			} catch (IOException e) {
				throw new Error(e);
			}
		}

		int nextInt() {
			return Integer.parseInt(next());
		}
	}

	Scanner in;
	PrintWriter out;

	class Point {
		int i;
		int j;
		char value;

		Point(int i, int j, char value) {
			this.i = i;
			this.j = j;
			this.value = value;
		}
	}

	void solve() {
		int n = in.nextInt();
		int m = in.nextInt();
		Point a[][] = new Point[n][m];
		for (int i = 0; i < n; i++) {
			String s = in.next();
			for (int j = 0; j < m; j++) {
				a[i][j] = new Point(i, j, s.charAt(j));
			}
		}
		boolean used[][] = new boolean[n][m];
		int col = 0;
		int max = 0;
		Queue<Point> q = new ArrayDeque<Point>();
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (!used[i][j] && a[i][j].value == '1') {
					col++;
					q.add(a[i][j]);
					used[i][j] = true;
					int sum = 1;
					while (!q.isEmpty()) {
						Point st = q.poll();
						int di = -1;
						int dj = 0;
						if (0 <= st.i + di && st.i + di < n && 0 <= st.j + dj
								&& st.j + dj < m) {
							if (!used[st.i + di][st.j + dj]
									&& a[st.i + di][st.j + dj].value == '1') {
								used[st.i + di][st.j + dj] = true;
								q.add(a[st.i + di][st.j + dj]);
								sum++;
							}
						}
						di = 1;
						dj = 0;
						if (0 <= st.i + di && st.i + di < n && 0 <= st.j + dj
								&& st.j + dj < m) {
							if (!used[st.i + di][st.j + dj]
									&& a[st.i + di][st.j + dj].value == '1') {
								used[st.i + di][st.j + dj] = true;
								q.add(a[st.i + di][st.j + dj]);
								sum++;
							}
						}
						di = 0;
						dj = -1;
						if (0 <= st.i + di && st.i + di < n && 0 <= st.j + dj
								&& st.j + dj < m) {
							if (!used[st.i + di][st.j + dj]
									&& a[st.i + di][st.j + dj].value == '1') {
								used[st.i + di][st.j + dj] = true;
								q.add(a[st.i + di][st.j + dj]);
								sum++;
							}
						}
						di = 0;
						dj = 1;
						if (0 <= st.i + di && st.i + di < n && 0 <= st.j + dj
								&& st.j + dj < m) {
							if (!used[st.i + di][st.j + dj]
									&& a[st.i + di][st.j + dj].value == '1') {
								used[st.i + di][st.j + dj] = true;
								q.add(a[st.i + di][st.j + dj]);
								sum++;
							}
						}
					}
					max = Math.max(max, sum);
				}
			}
		}
		out.println(col + " " + max);
	}

	void run() {
		in = new Scanner(System.in);
		out = new PrintWriter(System.out);
		try {
			solve();
		} finally {
			out.close();
		}
	}

	public static void main(String[] args) {
		new nC().run();
	}

}
