#include <iostream>
#include <fstream>
#include <sstream>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <assert.h>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>

//#define DEBUG 1

#define int long long
#define for0(i,n) for (int i=0; i<n; i++)
#define iter(c) for(auto it=c.begin(); it!=c.end(); it++)
#define vec(x) vector< x >
#define pb push_back
#define ms(a,z) memset(a,z,sizeof(a));
#define mp make_pair
#define X first
#define Y second
#define sqr(x) 1LL*(x)*(x)
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define all(a) a.begin(),a.end()
#define sz(x) (int)(x).size()
#ifdef int
#define read(x) scanf("%lld",&x);
#else
#define read(x) scanf("%d",&x);
#endif

#ifdef DEBUG
#define nl cout<<"\n";
#define pr(x) cout<<(x)<<" ";
#define prl(x) cout<<#x " = "<<x<<endl;
#define prp(x) cout<<"("<<(x).first<<" "<<(x).second<<") ";
#define printv(v) {for(int _=0; _<sz(v); _++) cout<<v[_]<<" "; cout<<"\n";}
#define printa(a,s) {for (int _=0; _<s; _++) cout<<a[_]<<" "; cout<<"\n";}
#define print2D(a,m,n) {for (int _=0; _<m; _++) {for (int __=0; __<n; __++) cout<<a[_][__]<<" "; cout<<"\n";} cout<<"\n";}
#define debug cout<<"ok at line "<<__LINE__<<endl;
#else
#define nl
#define pr(x)
#define prl(x)
#define prp(x)
#define printv(v)
#define printa(a,s)
#define print2D(a,m,n)
#define debug
#endif

using namespace std;

typedef long long ll;

const int INF = 2147483647;
const long long INFL = 9223372036854775807LL;
const double EPSILON = 0.00000001;
const long long MOD = 1000000007;

char grid[2005][2005];
bool a1[2005][2005], a2[2005][2005], a3[2005][2005];
int cache[2005];

void update_cache(int x, int h)
{
    for (int y=0; y<h; y++) {
        if (a3[y][x] == 0)
            cache[y]++;
        else 
            cache[y] = 0;
    }
}

int32_t main()
{
    #ifdef DEBUG
    freopen("D.txt","r",stdin);
    //freopen("","w",stdout);
    #endif

    int h,w;
    cin >> h >> w;
    for0(y,h) {
        scanf("%s",grid[y]);
    }
    for0(y,h) {
        for0(x,w) 
            a1[y][x] = grid[y][x] == '#';
    }
    for0(y,h-1) {
        for0(x,w) {
            a2[y][x] = a1[y][x] ^ a1[y+1][x];
        }
    }
    for0(y,h-1) {
        for0(x,w-1) {
            a3[y][x] = a2[y][x] ^ a2[y][x+1];
        }
    }
    h--; 
    w--;
    print2D(a3,h,w);
    
    ms(cache,0);
    int best = max(h+1,w+1);
    
    for (int x=w-1; x>=0; x--) {
        update_cache(x,h);
        stack<pair<int,int> > s, s2;
        s.push({-1,-1});
        s2.push({-1,-1});
        
        for (int y=0; y<=h; y++) { //go to h since cache[h] = 0 
            //pr(x) pr(y) nl
            int y0, w0;
            while (not s.empty() and s.top().second >= cache[y]) {
                s.pop();
            }
            while (not s2.empty() and s2.top().second > cache[y]) {
                tie(y0,w0) = s2.top();
                s2.pop();
                //pr("rect") pr(w0) pr(y-y0-1) nl 
                best = max(best, (w0+1)*(y-y0));
            }
            
            tie(y0,w0) = s.top();
            //pr("prev") pr(y0) pr(w0) nl
            //pr("pushing") pr(y) pr(y0) pr(cache[y]) nl
            s.push({y,cache[y]});
            s2.push({y0,cache[y]});
        }
        //nl
    }
    
    cout<<best<<endl;
    return 0;
}


Measured memory_bytes: 16000