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

#define NDEBUG
#ifdef DEBUG
#include "../cout11.h"
#undef NDEBUG
#endif
#include <cassert>

typedef long long ll;
typedef long double Double;
typedef unsigned long long ull;
typedef pair<int,int> ii;
typedef pair<ll,ll> llll;
typedef pair<double,double> dd;

typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef vector<ii> vii;
typedef vector<vector<ii>> vvii;
typedef vector<ll> vll;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<long double> vD;

#define sz(a)  int((a).size())
#define pb  push_back
#define FOR(var,from,to) for(int var=(from);var<=(to);++var)
#define rep(var,n)  for(int var=0;var<(n);++var)
#define rep1(var,n)  for(int var=1;var<=(n);++var)
#define repC2(vari,varj,n)  for(int vari=0;vari<(n)-1;++vari)for(int varj=vari+1;varj<(n);++varj)
#define ALL(c)  (c).begin(),(c).end()
#define RALL(c)  (c).rbegin(),(c).rend()
#define tr(i,c)  for(auto i=(c).begin(); i!=(c).end(); ++i)
#define found(s,e)  ((s).find(e)!=(s).end())
#define mset(arr,val)  memset(arr,val,sizeof(arr))
#define mid(x,y) ((x)+((y)-(x))/2)
#define IN(x,a,b) ((a)<=(x)&&(x)<=(b))
#define cons make_pair


long long max_box_area_in_histogram(vector<int>& a) {
    int N = a.size();

    vector<int> L(N);
    stack<int> st;

    for (int i=0; i<N; ++i) {
        while (!st.empty() && a[st.top()] >= a[i]) {
            st.pop();
        }
        L[i] = (st.empty() ? -1 : st.top())+1;
        st.push(i);
    }

    while (!st.empty()) st.pop();

    vector<int> R(N);
    for (int i=N-1; i>=0; --i) {
        while (!st.empty() && a[st.top()] >= a[i]) {
            st.pop();
        }
        R[i] = (st.empty() ? N : st.top())-1;
        st.push(i);
    }

    long long smax = 0;
    for (int i=0; i<N; ++i) {
        int h = a[i], w = R[i] - L[i] + 1;
        // ll s = (long long)h * w;
        ll s = (long long)(h + 1)*(w + 1);
        smax = max(smax, s);
    }

    return smax;
}

ll solve(int H, int W, vector<string>& s) {
    vvi a(H-1, vi(W-1, 0));
    rep(r, H-1) {
        rep(c, W-1) {
            a[r][c] = (s[r][c] == '#') ^ (s[r][c+1] == '#')
                    ^ (s[r+1][c] == '#') ^ (s[r+1][c+1] == '#');
        }
    }

    ll best = max(W, H);

    vi histo(W-1, 0);
    rep(r, H-1){
        rep(c, W-1) {
            if (a[r][c]) histo[c] = 0;
            else         histo[c]++;
        }
        best = max(best, max_box_area_in_histogram(histo));
    }

    return best;
}

int main() {
    int H, W; cin >> H >> W;
    vector<string> s(H);
    rep(i, H) cin >> s[i];
    cout << solve(H,W,s) << endl;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define stoi stoll
using ll=long long;
using vi=vector<int>;
using pii=pair<int,int>;
#define ALL(c) begin(c),end(c)
#define RALL(c) rbegin(c),rend(c)
#define ITR(i,b,e) for(auto i=(b);i!=(e);++i)
#define FORE(x,c) for(auto &x:c)
#define REPF(i,a,n) for(int i=a,i##len=(int)(n);i<i##len;++i)
#define REP(i,n) REPF(i,0,n)
#define REPR(i,n) for(int i=(int)(n);i>=0;--i)
#define SZ(c) ((int)c.size())
#define CONTAIN(c,x) (c.find(x)!=end(c))
#define OUTOFRANGE(y,x,h,w) ((y)<0||(x)<0||(y)>=(h)||(x)>=(w))
#define dump(...)
const signed INF_=1001001001; const ll INF=1001001001001001001LL;
const int DX[9]={0,1,0,-1,1,1,-1,-1,0},DY[9]={-1,0,1,0,-1,1,1,-1,0};
template<class T> ostream& operator<<(ostream &os,const vector<T> &v) {
    ITR(i,begin(v),end(v))os<<*i<<(i==end(v)-1?"":" ");return os;}
template<class T> istream& operator>>(istream &is,vector<T> &v) {
    ITR(i,begin(v),end(v)) is>>*i;return is;}
template<class T,class U> istream& operator>>(istream &is, pair<T,U> &p) {
    is>>p.first>>p.second;return is;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}return 0;}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}return 0;}
template<class T> using heap=priority_queue<T,vector<T>,greater<T>>;
struct{template<class T> operator T(){T x;cin>>x;return x;}} IN;
struct before_main_function {
    before_main_function() {
        cin.tie(0);ios::sync_with_stdio(false);
        cout<<setprecision(15)<<fixed;
        #define endl "\n"
    }
} before_main_function;
//------------------8<------------------------------------8<--------------------

int H,W;
vector<vector<int>> b;
int calc(int y) {
    int ret=0;
    stack<pair<int,int>> st;
    REP(j,W) {
        if(st.empty() || st.top().first<b[y][j]) {
            st.push({b[y][j],j});
        } else if(st.top().first>b[y][j]) {
            int idx=0;
            while(!st.empty() && st.top().first>b[y][j]) {
                auto tp=st.top();
                idx=tp.second;
                st.pop();
                chmax(ret,(j-tp.second+1)*tp.first);
            }
            st.push({b[y][j],idx});
        }
    }
    return ret;
}
signed main() {
    cin>>H>>W;
    vector<string> S(H);
    cin>>S;
    b=vector<vector<int>>(H,vector<int>(W,0));
    REP(j,W-1) {
        b[0][j]=1;
        REPF(i,1,H) {
            if((S[i][j]==S[i][j+1])==(S[i-1][j]==S[i-1][j+1])) {
                b[i][j]=b[i-1][j]+1;
            } else {
                b[i][j]=1;
            }
        }
    }
    int ans=max(H,W);
    REP(i,H) {
        chmax(ans,calc(i));
    }
    cout<<ans<<endl;
    return 0;
}

