/*
	*/

	#pragma GCC optimize("O3")
	#define _CRT_SECURE_NO_WARNINGS
	#include <fstream>
	#include <iostream>
	#include <string>
	#include <complex>
	#include <math.h>
	#include <set>
	#include <vector>
	#include <map>
	#include <queue>
	#include <stdio.h>
	#include <stack>
	#include <algorithm>
	#include <list>
	#include <ctime>

	#include <memory.h>
	#include <assert.h>

	#define y0 sdkfaslhagaklsldk

	#define y1 aasdfasdfasdf
	#define yn askfhwqriuperikldjk
	#define j1 assdgsdgasghsf
	#define tm sdfjahlfasfh
	#define lr asgasgash
	#define norm asdfasdgasdgsd
	#define have adsgagshdshfhds
	#define ends asdgahhfdsfshdshfd

	#define eps 1e-11
	#define M_PI 3.141592653589793
	#define bsize 512

	#define ldouble long double
	using namespace std;

	#define bs 1000000007
	const int N = 2031;

	int n,m;
	string st;
	int board[N][N];

	long long pw[N];

	char cc(int x)
	{
		return x+48;
	}

	int ans;
	string normalize(string st)
	{
		if (st[0]=='1')
		{
			for (int i=0;i<st.size();i++)
			{
				if (st[i]=='0')
					st[i]='1';
				else
					st[i]='0';
			}
		}
		return st;
	}

	long long H_down[N][N][2];
	int l[N],r[N];
	vector<pair<int,int> > events;
	int get_span(int ps)
	{
		return r[ps]-l[ps]+1;
	}

	void run_merge(int a,int b)
	{
		if (a>b)
			swap(a,b);
		r[l[a]]=r[b];
		l[r[b]]=l[a];
	}

	long long get_normalized(int row,int col,int span)
	{
		int v=board[row][col];
		long long s=H_down[row][col][v]-H_down[row+span][col][v];
		return s;
	}

	int get_lcp(int row,int col)
	{
		int l,r;
		l=0;
		r=n-row+1;
		while (l<r)
		{
			int mid=l+r+1;
			mid/=2;
			long long here1=get_normalized(row,col,mid);
			long long here2=get_normalized(row,col+1,mid);
			if (here1==here2)
				l=mid;
			else
				r=mid-1;
		}
		return l;
	}

	int main(){
		//freopen("tree.in","r",stdin);
		//freopen("tree.out","w",stdout);
		//freopen("input.txt", "r", stdin);
		//freopen("out.txt", "w", stdout);
		//ios_base::sync_with_stdio(0);
		//cin.tie(0);

		pw[0]=1;
		for (int i=1;i<=2000;i++)
		{
			pw[i]=pw[i-1]*137;
		}

		cin>>n>>m;

		for (int i=1;i<=n;i++)
		{
			cin>>st;
			for (int j=1;j<=m;j++)
			{
				if (st[j-1]=='#')
					board[i][j]=1;
				else
					board[i][j]=0;
			}
		}

	/*	for (int i=1;i<=n;i++)
		{
			for (int j=1;j<=m;j++)
			{
				for (int q=i;q<=n;q++)
				{
					for (int w=j;w<=m;w++)
					{
						vector<string> V;
						for (int p=i;p<=q;p++)
						{
							string temp="";
							for (int qq=j;qq<=w;qq++){
								temp+=cc(board[p][qq]);
							}
							temp=normalize(temp);
							V.push_back(temp);
						}
						sort(V.begin(),V.end());
						int ok=1;
						//cout<<V.size()<<" "<<i<<" "<<j<<" "<<q<<" "<<w<<endl;
						for(int qq=1;qq<V.size();qq++)
						{
							if (V[qq-1]!=V[qq])
								ok=0;
						}
						if (ok)
						{
							if ((q-i+1)*(w-j+1)==27)
							{
								cout<<i<<" "<<j<<" "<<q<<" "<<w<<endl;
							}
							ans=max(ans,(q-i+1)*(w-j+1));}
					}
				}
			}
		}

		cout<<ans<<endl;
	*/

		for (int i=n;i>=1;--i)
		{
			for (int j=m;j;--j)
			{
				H_down[i][j][0]=H_down[i+1][j][0]+board[i][j]*pw[i];
				H_down[i][j][1]=H_down[i+1][j][1]+(1-board[i][j])*pw[i];
			}
		}

		/*for (int i=1;i<=n;i++)
		{
			for (int j=1;j<=m;j++)
			{
				cout<<get_normalized(i,j,1)<<" ";
			}
			cout<<endl;
		}*/

		ans=max(n,m);

		for (int start_row=1;start_row<=n;start_row++)
		{
			for (int i=1;i<=m;i++)
			{
				l[i]=r[i]=i;
			}
			events.clear();
			for (int i=1;i<m;i++)
			{
				int here=get_lcp(start_row,i);
				events.push_back(make_pair(here,i));
		/*		if (start_row==2)
				{
					cout<<i<<" "<<here<<endl;
				}
	*/		}

			sort(events.begin(),events.end());
			reverse(events.begin(),events.end());

			for (int i=0;i<events.size();i++)
			{
				int cur_h=events[i].first;
				int ps=events[i].second;
				int new_span=get_span(ps)+get_span(ps+1);
				run_merge(ps,ps+1);
				ans=max(ans,new_span*cur_h);
			}
		}

		cout<<ans<<endl;

		cin.get(); cin.get();
		return 0;
	}


Measured memory_bytes: 80640