#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
using namespace std;

#define int64 long long
#define uint64 unsigned long long
#define pb push_back
#define mp make_pair


struct point {
	int x, y;
	point(int x, int y) {
		this->x = x;
		this->y = y;
	}
};

int main() {
	int m, n, i, j;
	cin >> m >> n;
	string str;
	getline(cin, str);
	vector< vector<int> > mask(m);
	for (i = 0; i < m; ++i) {
		mask[i].resize(n);
		getline(cin, str);
		for (j = 0; j < n; ++j) {
			mask[i][j] = str[j] == '1' ? -1 : 0;
		}
	}

	int c = 0, s = 0;
	for (i = 0; i < m; ++i) {
		for (j = 0; j < n; ++j) {
				if (mask[i][j] == -1) {
					mask[i][j] = ++c;
					queue<point> q;
					q.push(point(j, i));
					while (!q.empty()) {
						point p = q.front();
						q.pop();
						if (p.x > 0 && mask[p.y][p.x - 1] == -1) { q.push(point(p.x - 1, p.y)); mask[p.y][p.x - 1] = mask[p.y][p.x]; }
						if (p.x < n - 1 && mask[p.y][p.x + 1] == -1) { q.push(point(p.x + 1, p.y)); mask[p.y][p.x + 1] = mask[p.y][p.x]; }
						if (p.y > 0 && mask[p.y - 1][p.x] == -1) { q.push(point(p.x, p.y - 1)); mask[p.y - 1][p.x] = mask[p.y][p.x]; }
						if (p.y < m - 1 && mask[p.y + 1][p.x] == -1) { q.push(point(p.x, p.y + 1)); mask[p.y + 1][p.x] = mask[p.y][p.x]; }
					}
				}
		}
	}

	vector <int> cur(c + 1);
	for (i = 0; i < m; ++i) {
		for (j = 0; j < n; ++j) {
			++cur[mask[i][j]];
		}
	}

	for (i = 1; i <= c; ++i) if (cur[i] > s) s = cur[i];

	cout << c << ' ' << s << endl;
	return 0;
}