//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define ull unsigned long long
#define db long double
#define pb push_back
#define ppb pop_back
#define fi first
#define se second
#define mp make_pair
#define all(x) (x).begin(), (x).end()

void dout() { cerr << '\n'; }

template <typename Head, typename... Tail>
void dout(Head H, Tail... T) {
    cerr << " " << H;
    dout(T...);
}

#ifdef LOCAL
    #define dbg(...) cerr << #__VA_ARGS__, dout(__VA_ARGS__)
#else
    #define dbg(...) ;
#endif

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
typedef pair <int, int> pii;

const int N = 2007;
int n, m, adj[N][N], good[N][N];
int f[N][N], l[N][N], r[N][N];

int main() {
    ios_base::sync_with_stdio(false), cin.tie(NULL);
    #ifdef LOCAL
        freopen("input.txt", "r", stdin);
    #endif

    cin >> n >> m;
    char ch;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> ch;
            if (ch == '.') {
                adj[i][j] = 1;
            }
        }
    }
    for (int i = 1; i < n; i++) {
        for (int j = 1; j < m; j++) {
            good[i][j] = 1;
            if (adj[i][j] ^ adj[i][j + 1] ^ adj[i + 1][j] ^ adj[i + 1][j + 1]) {
                good[i][j] = 0;
            }
        }
    }
    for (int j = 1; j < m; j++) {
        for (int i = 1; i < n; i++) {
            if (good[i][j]) {
                f[i][j] = f[i - 1][j] + 1;
            }
        }
    }
    stack <int> st;
    int ans = max(n, m);
    for (int i = 1; i < n; i++) {
        for (int j = 1; j < m; j++) {
            while (!st.empty() && f[i][st.top()] >= f[i][j]) {
                st.pop();
            }
            if (st.empty()) {
                l[i][j] = 1;
            }   else {
                l[i][j] = st.top() + 1;
            }
            st.push(j);
        }
        while (!st.empty()) {
            st.pop();
        }
        for (int j = m - 1; j >= 1; j--) {
            while (!st.empty() && f[i][st.top()] >= f[i][j]) {
                st.pop();
            }
            if (st.empty()) {
                r[i][j] = m - 1;
            }   else {
                r[i][j] = st.top() - 1;
            }
            st.push(j);

            ans = max(ans, (r[i][j] - l[i][j] + 2) * (f[i][j] + 1));
        }
        while (!st.empty()) {
            st.pop();
        }
    }
    cout << ans;
}

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

int main() {
	int n;
	long long int m;
	while (cin >> n >> m) {
		if (n == 0 && m == 0) {
			break;
		}
		long long int b;
		vector<long long int> ss;
		ss.push_back(0);
		for (int i = 0; i < n; i++) {
			cin >> b;
			if (b <= m) {
				ss.push_back(b);
			}
		}
		vector<long long int> ss2;
		for (long long int i = 0; i < ss.size(); i++) {
			ss2.push_back(ss[i]);
			for (long long int j = i; j < ss.size(); j++) {
				if (ss[i]+ss[j] <= m) {
					ss2.push_back(ss[i]+ss[j]);
				}
			}
		}
		sort(ss2.begin(), ss2.end());
		/*for (long long int i = 0; i < ss2.size(); i++) {
			cout << ss2[i] << endl;
		}*/
		long long int MAX = 0;
		long long int sz = ss2.size();
		for (long long int j = 0; j < sz; j++) {
			long long int a = m;
			for (long long int i = 0; i < 2; i++) {
				vector<long long int>::iterator ite = upper_bound(ss2.begin(), ss2.end(), a);
				if (ite != ss.begin()) {
					ite--;
					a -= *(ite);
				}
			}
			vector<long long int>::iterator ite2 = ss2.end();
			ss2.erase(ite2-1);
			MAX = max(MAX, m-a);
		}
		cout << MAX << endl;
	}
	return 0;
}