#include<iostream>
#include<iomanip>
#include<cassert>
#include<stdexcept>
#include<utility>
#include<functional>
#include<numeric>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<array>
#include<stack>
#include<queue>
#include<deque>
#include<vector>
#include<complex>
#include<set>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<string>
#include<bitset>
#include<memory>
using namespace std;
using ll=long long;

int main(){
    int h,w;
    cin>>h>>w;
    vector<string> s(h);
    for(int i=0;i<h;i++) cin>>s[i];

    int res = max(h,w);
    vector<vector<int>> b(h-1,vector<int>(w-1));
    auto judge=[&](int i,int j){
        return (int)(s[i][j]=='#');
    };
    for(int i=0;i+1<h;i++){
        for(int j=0;j+1<w;j++){
            int cnt = judge(i,j) + judge(i+1,j) +judge(i,j+1) + judge(i+1,j+1);
            b[i][j] = (cnt%2==0);
        }  
    }

    vector<vector<int>> sum(h,vector<int>(w));
    for(int i=0;i<h-1;i++){
        for(int j=0;j<w-1;j++){
            if(b[i][j]) sum[i+1][j] = sum[i][j]+1;
        }
    }
    
    for(int i=0;i<h-1;i++){
        int x = i+1;
        stack<pair<int,int>> lh;
        lh.push({-1,0});
        for(int y=0;y<w;y++){
            while(sum[x][y]<lh.top().second){
                auto tmp = lh.top(); lh.pop();
                int height = tmp.second;
                int width = y-lh.top().first;
                res = max(res,width*(height+1));
            }
            lh.push({y,sum[x][y]});
        }
    }
    cout<<res<<endl;
    
    return 0;
}

#include <iostream>
#include <algorithm>
#include <bitset>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <complex>
#include <string.h>
#include <numeric>
using namespace std;

//#define int long long
#define reps(i,s,n) for(int (i)=(s);(i)<(n);++(i))
#define rep(i,n) reps(i,0,n)
#define rept(i,n) rep(i,(n)+1)
#define repst(i,s,n) reps(i,s,(n)+1)
#define reprt(i,n,t) for(int (i)=(n);(i)>=(t);--(i))
#define repr(i,n) reprt(i,n,0)
#define each(i,v) for(auto &(i):(v))
#define eachr(i,v) for(auto &(i)=(v).rbegin();(i)!=(v).rend();(i)++)
#define all(c) (c).begin(),(c).end()
#define rall(c) (c).rbegin(),(c).rend()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define tmax(x,y,z) max(x,max(y,z))
#define tmin(x,y,z) min(x,min(y,z))
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
#define ln '\n'
#define bln(i,n) (((i)==(n)-1)?'\n':' ')
#define dbg(x) cout<<#x" = "<<(x)<<ln<<flush
#define dbga(x,n) {cout<<#x" : ";for(int (i)=0;i<(n);++i){cout<<((x)[i])<<(i==((n)-1)?'\n':' ')<<flush;}}
#define zero(a) memset(a,0,sizeof(a))
#define unq(a) sort(all(a)),a.erase(unique(all(a)),a.end())

//typedef complex<double> P;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vst;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vector<int> > mat;

const ll inf = (ll)1e9+10;
const ll linf = (ll)1e18+10;
const ll mod = (ll)(1e9+7);
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const int ddx[] = {0, 1, 1, 1, 0, -1, -1, -1};
const int ddy[] = {1, 1, 0, -1, -1, -1, 0, 1};
const double eps = 1e-10;

ll mop(ll a,ll b,ll m=mod) {ll r=1;a%=m;for(;b;b>>=1){if(b&1)r=r*a%m;a=a*a%m;}return r;}
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
bool ool(int x,int y,int h,int w) {return((x<0)||(h<=x)||(y<0)||(w<=y));}
bool deq(double a,double b) {return abs(a-b)<eps;}

struct oreno_initializer {
	oreno_initializer() {
		cin.tie(0);
		ios::sync_with_stdio(0);
	}
} oreno_initializer;



// 2*2の正方形のうち黒の個数と白の個数がどちらも偶数のものは全部黒にできる
// どちらも奇数のものはできない(白黒反転は可)
// そういう正方形を内側に含まないような最大の長方形を求める

int h, w, ng[2020][2020], x[2020], res;
string s[2020];

signed main() {
	cin >> h >> w;
	res = max(h,w);
	rep(i,h) cin >> s[i];
	rep(i,h) {
		rep(j,w-1) {
			if (i && !(s[i-1][j]^s[i-1][j+1]^s[i][j]^s[i][j+1])) x[j]++;
			else x[j] = 1;
		}
		stack<int> s;
		rep(r,w) {
			while (!s.empty() && x[s.top()]>=x[r]) {
				int t = s.top(); s.pop();
				int l = (s.empty() ? -1 : s.top());
				chmax(res, x[t]*(r-l));
			}
			s.push(r);
		}
	}
	cout << res << endl;
}