#include "bits/stdc++.h"
using namespace std;

#define OUT(x)  cerr << #x << " = " << x << endl;
#define all(x)  x.begin(), x.end()
#define mp      make_pair
#define pii     pair<int, int>
#define piii    pair<int, pair<int, int>>

struct Rectangle { 
        int height, pos;
        Rectangle(int h, int p) : height(h), pos(p) {}
};
//1と0のグリッドにおいて1のマスのみを使って作る長方形の中で面積が最大のものの面積を返す
pair<int, vector<int>> LargestRectangle(vector<vector<int> > &s, int h, int w) {
        vector<vector<int> > t(h, vector<int> (w));
        for (int x = 0; x < w; x ++) for (int y = 0; y < h; y ++) {
                if (s[y][x] == 0) t[y][x] = 0;
                else t[y][x] = (y > 0) ? t[y - 1][x] + 1 : 1;
        }
        int res = 0;
        vector<int> highest;
        for (int y = 0; y < h; y ++) { 
                stack<Rectangle> st;
                int ma = 0;
                vector<int> height;
                t[y].resize(t.size() + 1);
                t[y][w] = 0;
                for (int x = 0; x <= w; x ++) {
                        Rectangle rect(t[y][x], x);
                        if (st.empty()) {
                                st.push(rect);
                        } else {
                                if (st.top().height < rect.height) {
                                        st.push(rect);
                                } else if (st.top().height > rect.height) {
                                        int target = x;
                                        while (!st.empty() && st.top().height >= rect.height) {
                                                Rectangle prev = st.top(); st.pop();
                                                int area = prev.height * (x - prev.pos);
                                                if (ma <= area) {
                                                        if (ma < area) height.clear();
                                                        height.push_back(prev.height);
                                                        ma = area;
                                                }
                                                target = prev.pos;
                                        }
                                        rect.pos = target;
                                        st.push(rect);
                                }
                        }
                }
                if (res <= ma) {
                        if (res < ma) highest.clear();
                        for (auto i : height) {
                                highest.push_back(i);
                        }
                        res = ma;
                }
        }
        return mp(res, highest);
}

int main() {
        int h, w;
        cin >> h >> w;
        vector<string> s(h);
        for (int y = 0; y < h; y ++) cin >> s[y];
        vector<vector<int> > t(2 * h - 1, vector<int> (2 * w - 1, 1));
        for (int y = 1; y < 2 * h - 2; y += 2) {
                for (int x = 1; x < 2 * w - 2; x += 2) {
                        int yy = y / 2, xx = x / 2;
                        int getxor = s[yy][xx] ^ s[yy + 1][xx] ^ s[yy][xx + 1] ^ s[yy + 1][xx + 1];
                        if (getxor) t[y][x] = 0;
                }
        }
        pair<int, vector<int>> get = LargestRectangle(t, 2 * h - 1, 2 * w - 1);
        int ans = max(w, h);
        for (int i = 0; i < get.second.size(); i ++) {
                int height = get.second[i];
                int width = get.first / height;
                int res = ((height + 1) / 2) * ((width + 1) / 2);
                ans = max(ans, res);
        }
        cout << ans << endl;
        return 0;
}



Measured memory_bytes: 169088