#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 s;
	getline(cin, s);
	vector< vector<bool> > mask(m), used(m);
	for (i = 0; i < m; ++i) {
		mask[i].resize(n);
		used[i].resize(n);
		getline(cin, s);
		for (j = 0; j < n; ++j) {
			used[i][j] = false;
			mask[i][j] = (s[j] == '1');
		}
	}

	int c = 0, q = 0;
	point p(0, 0);
	while (true) {
		used[p.y][p.x] = true;
		if (mask[p.y][p.x]) {
			++c;
			int cur = 0;
			queue<point> qu;
			qu.push(p);
			while (!qu.empty()) {
				++cur;
				point p2 = qu.front();
				qu.pop();
				used[p2.y][p2.x] = true;
				if (p2.x > 0 && mask[p2.y][p2.x - 1] && !used[p2.y][p2.x - 1]) qu.push(point(p2.x - 1, p2.y));
				if (p2.y > 0 && mask[p2.y - 1][p2.x] && !used[p2.y - 1][p2.x]) qu.push(point(p2.x, p2.y - 1));
				if (p2.x < n - 1 && mask[p2.y][p2.x + 1] && !used[p2.y][p2.x + 1]) qu.push(point(p2.x + 1, p2.y));
				if (p2.y < m - 1 && mask[p2.y + 1][p2.x] && !used[p2.y + 1][p2.x]) qu.push(point(p2.x, p2.y + 1));
			}

			if (cur > q) q = cur;
		}

		for (i = 0; i < m; ++i) {
			for (j = 0; j < n; ++j) {
				if (!used[i][j]) {
					p = point(j, i);
					goto next;
				}
			}
		}
		break;
next:;
	}

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