import java.io.*;
import java.util.*;
import java.util.stream.Stream;

public class icpc
{
    public static void main(String[] args) throws IOException
    {
        //Reader in = new Reader();
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String s1[] = in.readLine().split(" ");
        int n = Integer.parseInt(s1[0]);
        int m = Integer.parseInt(s1[1]);
        int[][] A = new int[n][m];
        for (int i=0;i<n;i++)
        {
            String s = in.readLine();
            for (int j=0;j<m;j++)   A[i][j] = s.charAt(j) - '0';
        }
        int[][] dp = new int[n][m];
        for(int i=0;i<n;i++)
        {
            if(A[i][m - 1] == 1)
                dp[i][m - 1] = 1;
        }
        for(int i=m - 2;i>=0;i--)
        {
            for (int j=0;j<n;j++)
            {
                if(A[j][i] == 1)
                    dp[j][i] = 1 + dp[j][i + 1];
            }
        }
        int max = Integer.MIN_VALUE;
        for (int i=0;i<m;i++)
        {
            int[] B = new int[n];
            for (int j=0;j<n;j++)   B[j] = dp[j][i];
            new MergeSortInt().sort(B, 0, n - 1);
            for (int j=0;j<n;j++)
                max = Math.max(max, (n - j) * B[j]);
        }
        System.out.println(max);

    }
}
class DSU
{
    int[] parent;
    int[] size;
    //Pass number of total nodes as parameter to the constructor
    DSU(int n)
    {
        this.parent = new int[n];
        this.size = new int[n];
        Arrays.fill(parent, -1);
    }

    public void makeSet(int v)
    {
        parent[v] = v;
        size[v] = 1;
    }

    public int findSet(int v)
    {
        if (v == parent[v]) return v;
        return parent[v] = findSet(parent[v]);
    }

    public void unionSets(int a, int b)
    {
        a = findSet(a);
        b = findSet(b);
        if (a != b)
        {
            if (size[a] < size[b])
            {
                int temp = a;
                a = b;
                b = temp;
            }
            parent[b] = a;
            size[a] += size[b];
        }
    }
}
class FastFourierTransform
{
    private void fft(double[] a, double[] b, boolean invert)
    {
        int count = a.length;
        for (int i = 1, j = 0; i < count; i++)
        {
            int bit = count >> 1;
            for (; j >= bit; bit >>= 1)
                j -= bit;
            j += bit;
            if (i < j)
            {
                double temp = a[i];
                a[i] = a[j];
                a[j] = temp;
                temp = b[i];
                b[i] = b[j];
                b[j] = temp;
            }
        }
        for (int len = 2; len <= count; len <<= 1)
        {
            int halfLen = len >> 1;
            double angle = 2 * Math.PI / len;
            if (invert)
                angle = -angle;
            double wLenA = Math.cos(angle);
            double wLenB = Math.sin(angle);
            for (int i = 0; i < count; i += len)
            {
                double wA = 1;
                double wB = 0;
                for (int j = 0; j < halfLen; j++)
                {
                    double uA = a[i + j];
                    double uB = b[i + j];
                    double vA = a[i + j + halfLen] * wA - b[i + j + halfLen] * wB;
                    double vB = a[i + j + halfLen] * wB + b[i + j + halfLen] * wA;
                    a[i + j] = uA + vA;
                    b[i + j] = uB + vB;
                    a[i + j + halfLen] = uA - vA;
                    b[i + j + halfLen] = uB - vB;
                    double nextWA = wA * wLenA - wB * wLenB;
                    wB = wA * wLenB + wB * wLenA;
                    wA = nextWA;
                }
            }
        }
        if (invert)
        {
            for (int i = 0; i < count; i++)
            {
                a[i] /= count;
                b[i] /= count;
            }
        }
    }

    public long[] multiply(long[] a, long[] b)
    {
        int resultSize = Integer.highestOneBit(Math.max(a.length, b.length) - 1) << 2;
        resultSize = Math.max(resultSize, 1);
        double[] aReal = new double[resultSize];
        double[] aImaginary = new double[resultSize];
        double[] bReal = new double[resultSize];
        double[] bImaginary = new double[resultSize];
        for (int i = 0; i < a.length; i++)
            aReal[i] = a[i];
        for (int i = 0; i < b.length; i++)
            bReal[i] = b[i];
        fft(aReal, aImaginary, false);
        fft(bReal, bImaginary, false);
        for (int i = 0; i < resultSize; i++)
        {
            double real = aReal[i] * bReal[i] - aImaginary[i] * bImaginary[i];
            aImaginary[i] = aImaginary[i] * bReal[i] + bImaginary[i] * aReal[i];
            aReal[i] = real;
        }
        fft(aReal, aImaginary, true);
        long[] result = new long[resultSize];
        for (int i = 0; i < resultSize; i++)
            result[i] = Math.round(aReal[i]);
        return result;
    }
}
class NumberTheory
{
    public boolean isPrime(long n)
    {
        if(n < 2)
            return false;
        for(long x = 2;x * x <= n;x++)
        {
            if(n % x == 0)
                return false;
        }
        return true;
    }
    public ArrayList<Long> primeFactorisation(long n)
    {
        ArrayList<Long> f = new ArrayList<>();
        for(long x=2;x * x <= n;x++)
        {
            while(n % x == 0)
            {
                f.add(x);
                n /= x;
            }
        }
        if(n > 1)
            f.add(n);
        return f;
    }
    public int[] sieveOfEratosthenes(int n)
    {
        //Returns an array with the smallest prime factor for each number and primes marked as 0
        int[] sieve = new int[n + 1];
        for(int x=2;x * x <= n;x++)
        {
            if(sieve[x] != 0)
                continue;
            for(int u=x*x;u<=n;u+=x)
            {
                if(sieve[u] == 0)
                {
                    sieve[u] = x;
                }
            }
        }
        return sieve;
    }
    public long gcd(long a, long b)
    {
        if(b == 0)
            return a;
        return gcd(b, a % b);
    }
    public long phi(long n)
    {
        double result = n;

        for(long p=2;p*p<=n;p++)
        {
            if(n % p == 0)
            {
                while (n % p == 0)
                    n /= p;
                result *= (1.0 - (1.0 / (double)p));
            }
        }
        if(n > 1)
            result *= (1.0 - (1.0 / (double)n));
        return (long)result;
    }
    public Name extendedEuclid(long a, long b)
    {
        if(b == 0)
            return new Name(a, 1, 0);
        Name n1 = extendedEuclid(b, a % b);
        Name n2 = new Name(n1.d, n1.y, n1.x - (long)Math.floor((double)a / b) * n1.y);
        return n2;
    }
    public long modularExponentiation(long a, long b, long n)
    {
        long d = 1L;
        String bString = Long.toBinaryString(b);
        for(int i=0;i<bString.length();i++)
        {
            d = (d * d) % n;
            if(bString.charAt(i) == '1')
                d = (d * a) % n;
        }
        return d;
    }
}
class Name
{
    long d;
    long x;
    long y;

    public Name(long d, long x, long y)
    {
        this.d = d;
        this.x = x;
        this.y = y;
    }
}
class SuffixArray
{
    int ALPHABET_SZ = 256, N;
    int[] T, lcp, sa, sa2, rank, tmp, c;

    public SuffixArray(String str)
    {
        this(toIntArray(str));
    }

    private static int[] toIntArray(String s)
    {
        int[] text = new int[s.length()];
        for (int i = 0; i < s.length(); i++) text[i] = s.charAt(i);
        return text;
    }

    public SuffixArray(int[] text)
    {
        T = text;
        N = text.length;
        sa = new int[N];
        sa2 = new int[N];
        rank = new int[N];
        c = new int[Math.max(ALPHABET_SZ, N)];
        construct();
        kasai();
    }

    private void construct()
    {
        int i, p, r;
        for (i = 0; i < N; ++i) c[rank[i] = T[i]]++;
        for (i = 1; i < ALPHABET_SZ; ++i) c[i] += c[i - 1];
        for (i = N - 1; i >= 0; --i) sa[--c[T[i]]] = i;
        for (p = 1; p < N; p <<= 1)
        {
            for (r = 0, i = N - p; i < N; ++i) sa2[r++] = i;
            for (i = 0; i < N; ++i) if (sa[i] >= p) sa2[r++] = sa[i] - p;
            Arrays.fill(c, 0, ALPHABET_SZ, 0);
            for (i = 0; i < N; ++i) c[rank[i]]++;
            for (i = 1; i < ALPHABET_SZ; ++i) c[i] += c[i - 1];
            for (i = N - 1; i >= 0; --i) sa[--c[rank[sa2[i]]]] = sa2[i];
            for (sa2[sa[0]] = r = 0, i = 1; i < N; ++i)
            {
                if (!(rank[sa[i - 1]] == rank[sa[i]]
                        && sa[i - 1] + p < N
                        && sa[i] + p < N
                        && rank[sa[i - 1] + p] == rank[sa[i] + p])) r++;
                sa2[sa[i]] = r;
            }
            tmp = rank;
            rank = sa2;
            sa2 = tmp;
            if (r == N - 1) break;
            ALPHABET_SZ = r + 1;
        }
    }

    private void kasai()
    {
        lcp = new int[N];
        int[] inv = new int[N];
        for (int i = 0; i < N; i++) inv[sa[i]] = i;
        for (int i = 0, len = 0; i < N; i++)
        {
            if (inv[i] > 0)
            {
                int k = sa[inv[i] - 1];
                while ((i + len < N) && (k + len < N) && T[i + len] == T[k + len]) len++;
                lcp[inv[i] - 1] = len;
                if (len > 0) len--;
            }
        }
    }
}
class ZAlgorithm
{
    public int[] calculateZ(char input[])
    {
        int Z[] = new int[input.length];
        int left = 0;
        int right = 0;
        for(int k = 1; k < input.length; k++) {
            if(k > right) {
                left = right = k;
                while(right < input.length && input[right] == input[right - left]) {
                    right++;
                }
                Z[k] = right - left;
                right--;
            } else {
                //we are operating inside box
                int k1 = k - left;
                //if value does not stretches till right bound then just copy it.
                if(Z[k1] < right - k + 1) {
                    Z[k] = Z[k1];
                } else { //otherwise try to see if there are more matches.
                    left = k;
                    while(right < input.length && input[right] == input[right - left]) {
                        right++;
                    }
                    Z[k] = right - left;
                    right--;
                }
            }
        }
        return Z;
    }
    public ArrayList<Integer> matchPattern(char text[], char pattern[])
    {
        char newString[] = new char[text.length + pattern.length + 1];
        int i = 0;
        for(char ch : pattern) {
            newString[i] = ch;
            i++;
        }
        newString[i] = '$';
        i++;
        for(char ch : text) {
            newString[i] = ch;
            i++;
        }
        ArrayList<Integer> result = new ArrayList<>();
        int Z[] = calculateZ(newString);

        for(i = 0; i < Z.length ; i++) {
            if(Z[i] == pattern.length) {
                result.add(i - pattern.length - 1);
            }
        }
        return result;
    }
}
class KMPAlgorithm
{
    public int[] computeTemporalArray(char[] pattern)
    {
        int[] lps = new int[pattern.length];

        int index = 0;
        for(int i=1;i<pattern.length;)
        {
            if(pattern[i] == pattern[index])
            {
                lps[i] = index + 1;
                index++;
                i++;
            }
            else
            {
                if(index != 0)
                {
                    index = lps[index - 1];
                }
                else
                {
                    lps[i] = 0;
                    i++;
                }
            }
        }
        return lps;
    }

    public ArrayList<Integer> KMPMatcher(char[] text, char[] pattern)
    {
        int[] lps = computeTemporalArray(pattern);

        int j = 0;
        int i = 0;
        int n = text.length;
        int m = pattern.length;
        ArrayList<Integer> indices = new ArrayList<>();
        while(i < n)
        {
            if(pattern[j] == text[i])
            {
                i++;
                j++;
            }
            if(j == m)
            {
                indices.add(i - j);
                j = lps[j - 1];
            }
            else if(i < n && pattern[j] != text[i])
            {
                if(j != 0)
                    j = lps[j - 1];
                else
                    i = i + 1;
            }
        }
        return indices;
    }
}
class Hashing
{
    public long[] computePowers(long p, int n, long m)
    {
        long[] powers = new long[n];
        powers[0] = 1;
        for(int i=1;i<n;i++)
        {
            powers[i] = (powers[i - 1] * p) % m;
        }
        return powers;
    }
    public long computeHash(String s)
    {
        long p = 31;
        long m = 1_000_000_009;
        long hashValue = 0L;
        long[] powers = computePowers(p, s.length(), m);
        for(int i=0;i<s.length();i++)
        {
            char ch = s.charAt(i);
            hashValue = (hashValue + (ch - 'a' + 1) * powers[i]) % m;
        }
        return hashValue;
    }
}
class BasicFunctions
{
    public long min(long[] A)
    {
        long min = Long.MAX_VALUE;
        for(int i=0;i<A.length;i++)
        {
            min = Math.min(min, A[i]);
        }
        return min;
    }
    public long max(long[] A)
    {
        long max = Long.MAX_VALUE;
        for(int i=0;i<A.length;i++)
        {
            max = Math.max(max, A[i]);
        }
        return max;
    }
}
class MergeSortInt
{
    // Merges two subarrays of arr[].
    // First subarray is arr[l..m]
    // Second subarray is arr[m+1..r]
    void merge(int arr[], int l, int m, int r) {
        // Find sizes of two subarrays to be merged
        int n1 = m - l + 1;
        int n2 = r - m;

        /* Create temp arrays */
        int L[] = new int[n1];
        int R[] = new int[n2];

        /*Copy data to temp arrays*/
        for (int i = 0; i < n1; ++i)
            L[i] = arr[l + i];
        for (int j = 0; j < n2; ++j)
            R[j] = arr[m + 1 + j];

        /* Merge the temp arrays */

        // Initial indexes of first and second subarrays
        int i = 0, j = 0;

        // Initial index of merged subarry array
        int k = l;
        while (i < n1 && j < n2) {
            if (L[i] <= R[j]) {
                arr[k] = L[i];
                i++;
            } else {
                arr[k] = R[j];
                j++;
            }
            k++;
        }

        /* Copy remaining elements of L[] if any */
        while (i < n1) {
            arr[k] = L[i];
            i++;
            k++;
        }

        /* Copy remaining elements of R[] if any */
        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }
    }

    // Main function that sorts arr[l..r] using
    // merge()
    void sort(int arr[], int l, int r) {
        if (l < r) {
            // Find the middle point
            int m = (l + r) / 2;

            // Sort first and second halves
            sort(arr, l, m);
            sort(arr, m + 1, r);

            // Merge the sorted halves
            merge(arr, l, m, r);
        }
    }

}
class MergeSortLong
{
    // Merges two subarrays of arr[].
    // First subarray is arr[l..m]
    // Second subarray is arr[m+1..r]
    void merge(long arr[], int l, int m, int r) {
        // Find sizes of two subarrays to be merged
        int n1 = m - l + 1;
        int n2 = r - m;

        /* Create temp arrays */
        long L[] = new long[n1];
        long R[] = new long[n2];

        /*Copy data to temp arrays*/
        for (int i = 0; i < n1; ++i)
            L[i] = arr[l + i];
        for (int j = 0; j < n2; ++j)
            R[j] = arr[m + 1 + j];

        /* Merge the temp arrays */

        // Initial indexes of first and second subarrays
        int i = 0, j = 0;

        // Initial index of merged subarry array
        int k = l;
        while (i < n1 && j < n2) {
            if (L[i] <= R[j]) {
                arr[k] = L[i];
                i++;
            } else {
                arr[k] = R[j];
                j++;
            }
            k++;
        }

        /* Copy remaining elements of L[] if any */
        while (i < n1) {
            arr[k] = L[i];
            i++;
            k++;
        }

        /* Copy remaining elements of R[] if any */
        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }
    }

    // Main function that sorts arr[l..r] using
    // merge()
    void sort(long arr[], int l, int r) {
        if (l < r) {
            // Find the middle point
            int m = (l + r) / 2;

            // Sort first and second halves
            sort(arr, l, m);
            sort(arr, m + 1, r);

            // Merge the sorted halves
            merge(arr, l, m, r);
        }
    }
}
class Node
{

    int x;
    int y;

    public Node(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    @Override
    public boolean equals(Object ob)
    {
        if(ob == null)
            return false;
        if(!(ob instanceof Node))
            return false;
        if(ob == this)
            return true;
        Node obj = (Node)ob;
        if(this.x == obj.x && this.y == obj.y)
            return true;
        return false;
    }

    @Override
    public int hashCode()
    {
        return (int)this.x;
    }
}
class Reader
{
    final private int BUFFER_SIZE = 1 << 16;
    private DataInputStream din;
    private byte[] buffer;
    private int bufferPointer, bytesRead;

    public Reader()
    {
        din = new DataInputStream(System.in);
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public Reader(String file_name) throws IOException
    {
        din = new DataInputStream(new FileInputStream(file_name));
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public String readLine() throws IOException
    {
        byte[] buf = new byte[64]; // line length
        int cnt = 0, c;
        while ((c = read()) != -1)
        {
            if (c == '\n')
                break;
            buf[cnt++] = (byte) c;
        }
        return new String(buf, 0, cnt);
    }

    public int nextInt() throws IOException
    {
        int ret = 0;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do
        {
            ret = ret * 10 + c - '0';
        }  while ((c = read()) >= '0' && c <= '9');

        if (neg)
            return -ret;
        return ret;
    }

    public long nextLong() throws IOException
    {
        long ret = 0;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do {
            ret = ret * 10 + c - '0';
        }
        while ((c = read()) >= '0' && c <= '9');
        if (neg)
            return -ret;
        return ret;
    }

    public double nextDouble() throws IOException
    {
        double ret = 0, div = 1;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();

        do {
            ret = ret * 10 + c - '0';
        }
        while ((c = read()) >= '0' && c <= '9');

        if (c == '.')
        {
            while ((c = read()) >= '0' && c <= '9')
            {
                ret += (c - '0') / (div *= 10);
            }
        }

        if (neg)
            return -ret;
        return ret;
    }

    private void fillBuffer() throws IOException
    {
        bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
        if (bytesRead == -1)
            buffer[0] = -1;
    }

    private byte read() throws IOException
    {
        if (bufferPointer == bytesRead)
            fillBuffer();
        return buffer[bufferPointer++];
    }

    public void close() throws IOException
    {
        if (din == null)
            return;
        din.close();
    }
}
class FenwickTree
{
    public void update(long[] fenwickTree,long delta,int index)
    {
        index += 1;
        while(index < fenwickTree.length)
        {
            fenwickTree[index] += delta;
            index = index + (index & (-index));
        }
    }
    public long prefixSum(long[] fenwickTree,int index)
    {
        long sum = 0L;
        index += 1;
        while(index > 0)
        {
            sum += fenwickTree[index];
            index -= (index & (-index));
        }
        return sum;
    }
}
class SegmentTree
{
    public int nextPowerOfTwo(int num)
    {
        if(num == 0)
            return 1;
        if(num > 0 && (num & (num - 1)) == 0)
            return num;
        while((num &(num - 1)) > 0)
        {
            num = num & (num - 1);
        }
        return num << 1;
    }
    public int[] createSegmentTree(int[] input)
    {
        int np2 = nextPowerOfTwo(input.length);
        int[] segmentTree = new int[np2 * 2 - 1];

        for(int i=0;i<segmentTree.length;i++)
            segmentTree[i] = Integer.MIN_VALUE;

        constructSegmentTree(segmentTree,input,0,input.length-1,0);
        return segmentTree;

    }
    private void constructSegmentTree(int[] segmentTree,int[] input,int low,int high,int pos)
    {
        if(low == high)
        {
            segmentTree[pos] = input[low];
            return;
        }
        int mid = (low + high)/ 2;
        constructSegmentTree(segmentTree,input,low,mid,2*pos + 1);
        constructSegmentTree(segmentTree,input,mid+1,high,2*pos + 2);
        segmentTree[pos] = Math.max(segmentTree[2*pos + 1],segmentTree[2*pos + 2]);
    }
    public int rangeMinimumQuery(int []segmentTree,int qlow,int qhigh,int len)
    {
        return rangeMinimumQuery(segmentTree,0,len-1,qlow,qhigh,0);
    }
    private int rangeMinimumQuery(int segmentTree[],int low,int high,int qlow,int qhigh,int pos)
    {
        if(qlow <= low && qhigh >= high){
            return segmentTree[pos];
        }
        if(qlow > high || qhigh < low){
            return Integer.MIN_VALUE;
        }
        int mid = (low+high)/2;
        return Math.max(rangeMinimumQuery(segmentTree, low, mid, qlow, qhigh, 2 * pos + 1),
                rangeMinimumQuery(segmentTree, mid + 1, high, qlow, qhigh, 2 * pos + 2));
    }
}
class Trie
{

    private class TrieNode
    {
        Map<Character, TrieNode> children;
        boolean endOfWord;
        public TrieNode()
        {
            children = new HashMap<>();
            endOfWord = false;
        }
    }

    private final TrieNode root;
    public Trie()
    {
        root = new TrieNode();
    }

    public void insert(String word)
    {
        TrieNode current = root;
        for (int i = 0; i < word.length(); i++)
        {
            char ch = word.charAt(i);
            TrieNode node = current.children.get(ch);
            if (node == null)
            {
                node = new TrieNode();
                current.children.put(ch, node);
            }
            current = node;
        }
        current.endOfWord = true;
    }

    public boolean search(String word)
    {
        TrieNode current = root;
        for (int i = 0; i < word.length(); i++)
        {
            char ch = word.charAt(i);
            TrieNode node = current.children.get(ch);
            if (node == null)
            {
                return false;
            }
            current = node;
        }
        return current.endOfWord;
    }

    public void delete(String word)
    {
        delete(root, word, 0);
    }

    private boolean delete(TrieNode current, String word, int index)
    {
        if (index == word.length())
        {
            if (!current.endOfWord)
            {
                return false;
            }
            current.endOfWord = false;
            return current.children.size() == 0;
        }
        char ch = word.charAt(index);
        TrieNode node = current.children.get(ch);
        if (node == null)
        {
            return false;
        }
        boolean shouldDeleteCurrentNode = delete(node, word, index + 1);

        if (shouldDeleteCurrentNode)
        {
            current.children.remove(ch);
            return current.children.size() == 0;
        }
        return false;
    }
}
class SegmentTreeLazy
{
    public int nextPowerOfTwo(int num)
    {
        if(num == 0)
            return 1;
        if(num > 0 && (num & (num - 1)) == 0)
            return num;
        while((num &(num - 1)) > 0)
        {
            num = num & (num - 1);
        }
        return num << 1;
    }

    public int[] createSegmentTree(int input[])
    {
        int nextPowOfTwo = nextPowerOfTwo(input.length);
        int segmentTree[] = new int[nextPowOfTwo*2 -1];

        for(int i=0; i < segmentTree.length; i++){
            segmentTree[i] = Integer.MAX_VALUE;
        }
        constructMinSegmentTree(segmentTree, input, 0, input.length - 1, 0);
        return segmentTree;
    }

    private void constructMinSegmentTree(int segmentTree[], int input[], int low, int high,int pos)
    {
        if(low == high)
        {
            segmentTree[pos] = input[low];
            return;
        }
        int mid = (low + high)/2;
        constructMinSegmentTree(segmentTree, input, low, mid, 2 * pos + 1);
        constructMinSegmentTree(segmentTree, input, mid + 1, high, 2 * pos + 2);
        segmentTree[pos] = Math.min(segmentTree[2*pos+1], segmentTree[2*pos+2]);
    }

    public void updateSegmentTreeRangeLazy(int input[], int segmentTree[], int lazy[], int startRange, int endRange, int delta)
    {
        updateSegmentTreeRangeLazy(segmentTree, lazy, startRange, endRange, delta, 0, input.length - 1, 0);
    }

    private void updateSegmentTreeRangeLazy(int segmentTree[], int lazy[], int startRange, int endRange, int delta, int low, int high, int pos)
    {
        if(low > high)
        {
            return;
        }
        if (lazy[pos] != 0)
        {
            segmentTree[pos] += lazy[pos];
            if (low != high)
            {
                lazy[2 * pos + 1] += lazy[pos];
                lazy[2 * pos + 2] += lazy[pos];
            }
            lazy[pos] = 0;
        }

        if(startRange > high || endRange < low)
        {
            return;
        }

        if(startRange <= low && endRange >= high)
        {
            segmentTree[pos] += delta;
            if(low != high) {
                lazy[2*pos + 1] += delta;
                lazy[2*pos + 2] += delta;
            }
            return;
        }

        int mid = (low + high)/2;
        updateSegmentTreeRangeLazy(segmentTree, lazy, startRange, endRange, delta, low, mid, 2*pos+1);
        updateSegmentTreeRangeLazy(segmentTree, lazy, startRange, endRange, delta, mid+1, high, 2*pos+2);
        segmentTree[pos] = Math.min(segmentTree[2*pos + 1], segmentTree[2*pos + 2]);
    }

    public int rangeMinimumQueryLazy(int segmentTree[], int lazy[], int qlow, int qhigh, int len)
    {
        return rangeMinimumQueryLazy(segmentTree, lazy, qlow, qhigh, 0, len - 1, 0);
    }

    private int rangeMinimumQueryLazy(int segmentTree[], int lazy[], int qlow, int qhigh, int low, int high, int pos)
    {
        if(low > high)
        {
            return Integer.MAX_VALUE;
        }
        if (lazy[pos] != 0)
        {
            segmentTree[pos] += lazy[pos];
            if (low != high)
            {
                lazy[2 * pos + 1] += lazy[pos];
                lazy[2 * pos + 2] += lazy[pos];
            }
            lazy[pos] = 0;
        }

        if(qlow > high || qhigh < low)
        {
            return Integer.MAX_VALUE;
        }

        if(qlow <= low && qhigh >= high)
        {
            return segmentTree[pos];
        }

        int mid = (low+high)/2;
        return Math.min(rangeMinimumQueryLazy(segmentTree, lazy, qlow, qhigh, low, mid, 2 * pos + 1), rangeMinimumQueryLazy(segmentTree, lazy,  qlow, qhigh, mid + 1, high, 2 * pos + 2));
    }
}


import java.util.*;
import java.io.*;
public class MaximumSubmatrix2 {

    /************************ SOLUTION STARTS HERE ************************/

    private static void solve() {

        int N = nextInt();
        int M = nextInt();

        char grid[][] = new char[N][];
        for(int i = 0; i < N; i++)
            grid[i] = nextLine().toCharArray();

        int DP[][] = new int[M][N]; // DP[i][j] = stores the largest block of 1 to the left of (j , i)

        for(int i = 0; i < N; i++) {
            DP[0][i] = grid[i][0] == '1' ? 1 : 0;
            for(int j = 1; j < M; j++)
                DP[j][i] = grid[i][j] == '1' ? DP[j - 1][i] + 1 : 0;
        }

        for(int i = 0; i < M; i++)
            Arrays.sort(DP[i]);

        int maxArea = 0;
        for(int i = 0; i < M; i++)
            for(int j = 0; j < N; j++)
                maxArea = Math.max(maxArea , (N - j) * DP[i][j]);

        println(maxArea);
    }

    /************************ SOLUTION ENDS HERE ************************/

    /************************ TEMPLATE STARTS HERE **********************/

    public static void main(String[] args) throws IOException {
        reader = new BufferedReader(new InputStreamReader(System.in));
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)), false);
        st     = null;
        solve();
        reader.close();
        writer.close();
    }

    static BufferedReader reader;
    static PrintWriter    writer;
    static StringTokenizer st;

    static String next()
    {while(st == null || !st.hasMoreTokens()){try{String line = reader.readLine();if(line == null){return null;}
    st = new StringTokenizer(line);}catch (Exception e){throw new RuntimeException();}}return st.nextToken();}
    static String nextLine()  {String s=null;try{s=reader.readLine();}catch(IOException e){e.printStackTrace();}return s;}
    static int    nextInt()   {return Integer.parseInt(next());}
    static long   nextLong()  {return Long.parseLong(next());}
    static double nextDouble(){return Double.parseDouble(next());}
    static char   nextChar()  {return next().charAt(0);}
    static int[]  nextIntArray(int n)         {int[] a= new int[n];   int i=0;while(i<n){a[i++]=nextInt();}  return a;}
    static long[] nextLongArray(int n)        {long[]a= new long[n];  int i=0;while(i<n){a[i++]=nextLong();} return a;}
    static int[]  nextIntArrayOneBased(int n) {int[] a= new int[n+1]; int i=1;while(i<=n){a[i++]=nextInt();} return a;}
    static long[] nextLongArrayOneBased(int n){long[]a= new long[n+1];int i=1;while(i<=n){a[i++]=nextLong();}return a;}
    static void   print(Object o)  { writer.print(o);  }
    static void   println(Object o){ writer.println(o);}

    /************************ TEMPLATE ENDS HERE ************************/

}


import java.awt.*;
import java.io.*;
import java.util.*;

public class Drogon {
    static long L,R;
    public static void main(String[] args) throws Exception {
        FastReader sc = new FastReader();
        int n=sc.nextInt(),m=sc.nextInt();
        int arr[][]=new int[n][m];
        for (int i=0;i<n;i++){
            String s=sc.next();
            for (int j=0;j<m;j++){
                if (s.charAt(j)=='1')arr[i][j]=1;
            }
        }
        for (int i=0;i<n;i++){
            for (int j=1;j<m;j++){
                if (arr[i][j]!=0)arr[i][j]+=arr[i][j-1];
            }
        }
        int cnt[][]=new int[m][1002];
        for (int i=0;i<m;i++){
            for (int j=0;j<n;j++){
                cnt[i][arr[j][i]]++;
            }
        }
        for (int i=0;i<m;i++){
            for (int j=1000;j>=0;j--){
                cnt[i][j]+=cnt[i][j+1];
            }
        }
        int max=-Integer.MAX_VALUE;
        for (int i=0;i<m;i++){
            for (int j=0;j<1001;j++){
                max=Math.max(max,cnt[i][j]*j);
            }
        }
        System.out.println(max);
    }
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new
                    InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}


import java.awt.*;
import java.io.*;
import java.util.*;

public class Drogon {
    static long L,R;
    public static void main(String[] args) throws Exception {
        FastReader sc = new FastReader();
        int n=sc.nextInt(),m=sc.nextInt();
        int arr[][]=new int[n][m];
        for (int i=0;i<n;i++){
            String s=sc.next();
            for (int j=0;j<m;j++){
                if (s.charAt(j)=='1')arr[i][j]=1;
            }
        }
        for (int i=0;i<n;i++){
            for (int j=1;j<m;j++){
                if (arr[i][j]!=0)arr[i][j]+=arr[i][j-1];
            }
        }
        int cnt[][]=new int[m][5002];
        for (int i=0;i<m;i++){
            for (int j=0;j<n;j++){
                cnt[i][arr[j][i]]++;
            }
        }
        for (int i=0;i<m;i++){
            for (int j=5000;j>=0;j--){
                cnt[i][j]+=cnt[i][j+1];
            }
        }
        int max=-Integer.MAX_VALUE;
        for (int i=0;i<m;i++){
            for (int j=0;j<5001;j++){
                max=Math.max(max,cnt[i][j]*j);
            }
        }
        System.out.println(max);
    }
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new
                    InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}


import java.util.HashMap;
import java.util.Scanner;

public class _23_Maximum_submatrix_2 {

	public static void main(String[] args) {
		Scanner scn = new Scanner(System.in);
		int n = scn.nextInt();
		int m = scn.nextInt();
		HashMap<Integer, Integer> st = new HashMap<>();
		int [][]dp=new int[m][m+1];
		for (int i = 0; i < n; i++) {
			String s = scn.next();
			int prev = -1;
			for (int j = 0; j < s.length(); j++) {
				if (s.charAt(j) == '1') {

					dp[j][j-prev]++;

				} else {
					prev = j;
				}
			}
		}
		long max = 0;
		for (int r = m - 1; r >= 0; r--) {
			int rs = 0;

			for (int len = r + 1; len > 0; len--) {
				int s = r*31111111+ len;
				int v2=dp[r][len];
//				if(st.containsKey(s)){
//					int val = st.get(s);
					rs += v2;
//				}

				max = Math.max(rs*len, max);

			}

		}
		System.out.println(max);
	}

}


import java.util.HashMap;
import java.util.Scanner;

public class _23_Maximum_submatrix_2 {

	public static void main(String[] args) {
		Scanner scn = new Scanner(System.in);
		int n = scn.nextInt();
		int m = scn.nextInt();
		HashMap<String, Integer> st = new HashMap<>();
		for (int i = 0; i < n; i++) {
			String s = scn.next();
			int prev = -1;
			for (int j = 0; j < s.length(); j++) {
				if (s.charAt(j) == '1') {
					String ls = j + "#" + (j - prev);
					if (st.containsKey(ls)) {
						st.put(ls, st.get(ls) + 1);
					} else {
						st.put(ls, 1);
					}
				} else {
					prev = j;
				}
			}
		}
		int max = 0;
		for (int r = n - 1; r >= 0; r--) {
			int rs = 0;
			for (int len = r + 1; len > 0; len--) {
				String s = r + "#" + len;
				if(st.containsKey(s)){
					int val = st.get(s);
					rs += val;
				}

				max = Math.max(rs*len, max);

			}

		}
		System.out.println(max);
	}

}


import java.util.HashMap;
import java.util.Scanner;

public class _23_Maximum_submatrix_2 {

	public static void main(String[] args) {
		Scanner scn = new Scanner(System.in);
		int n = scn.nextInt();
		int m = scn.nextInt();
		HashMap<Integer, Integer> st = new HashMap<>();
		for (int i = 0; i < n; i++) {
			String s = scn.next();
			int prev = -1;
			for (int j = 0; j < s.length(); j++) {
				if (s.charAt(j) == '1') {
					int ls = j*31111111 + (j - prev);
					if (st.containsKey(ls)) {
						st.put(ls, st.get(ls) + 1);
					} else {
						st.put(ls, 1);
					}
				} else {
					prev = j;
				}
			}
		}
		long max = 0;
		for (int r = m - 1; r >= 0; r--) {
			int rs = 0;

			for (int len = r + 1; len > 0; len--) {
				int s = r*31111111+ len;
				if(st.containsKey(s)){
					int val = st.get(s);
					rs += val;
				}

				max = Math.max(rs*len, max);

			}

		}
		System.out.println(max);
	}

}


import java.util.HashMap;
import java.util.Scanner;

public class _23_Maximum_submatrix_2 {

	public static void main(String[] args) {
		Scanner scn = new Scanner(System.in);
		int n = scn.nextInt();
		int m = scn.nextInt();
		HashMap<String, Integer> st = new HashMap<>();
		for (int i = 0; i < n; i++) {
			String s = scn.next();
			int prev = -1;
			for (int j = 0; j < s.length(); j++) {
				if (s.charAt(j) == '1') {
					String ls = j + "#" + (j - prev);
					if (st.containsKey(ls)) {
						st.put(ls, st.get(ls) + 1);
					} else {
						st.put(ls, 1);
					}
				} else {
					prev = j;
				}
			}
		}
		long max = 0;
		for (int r = n - 1; r >= 0; r--) {
			int rs = 0;
			for (int len = r + 1; len > 0; len--) {
				String s = r + "#" + len;
				if(st.containsKey(s)){
					int val = st.get(s);
					rs += val;
				}

				max = Math.max(rs*len, max);

			}

		}
		System.out.println(max);
	}

}


import java.util.HashMap;
import java.util.Scanner;

public class _23_Maximum_submatrix_2 {

	public static void main(String[] args) {
		Scanner scn = new Scanner(System.in);
		int n = scn.nextInt();
		int m = scn.nextInt();
		HashMap<String, Integer> st = new HashMap<>();
		for (int i = 0; i < n; i++) {
			String s = scn.next();
			int prev = -1;
			for (int j = 0; j < s.length(); j++) {
				if (s.charAt(j) == '1') {
					String ls = j + "#" + (j - prev);
					if (st.containsKey(ls)) {
						st.put(ls, st.get(ls) + 1);
					} else {
						st.put(ls, 1);
					}
				} else {
					prev = j;
				}
			}
		}
		long max = 0;
		for (int r = m - 1; r >= 0; r--) {
			int rs = 0;

			for (int len = r + 1; len > 0; len--) {
				String s = r + "#" + len;
				if(st.containsKey(s)){
					int val = st.get(s);
					rs += val;
				}

				max = Math.max(rs*len, max);

			}

		}
		System.out.println(max);
	}

}


import java.io.*;
import java.util.*;

public class Myclass {
     public static ArrayList a[]=new ArrayList[3000001];
     public static boolean isPrime[]=new boolean [1000001];
     public static Vector<Integer>v=new Vector<>();
     static void pre() {
    	 Arrays.fill(isPrime, true);
    	 isPrime[0]=false;
    	 isPrime[1]=false;
    	 for(int i=2;i*i<=1e6;i++) {
    		 if(isPrime[i]) {
    			 for(int j=2*i;j<=1e6;j+=i) {
    				 isPrime[j]=false;
    			 }
    		 }
    	 }

     }
     public static void main(String[] args) throws FileNotFoundException
    {
    	InputReader in=new InputReader(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        int n=in.nextInt();
        int m=in.nextInt();
        char a[][]=new char[n][m];
        for(int i=0;i<n;i++) {
        	a[i]=in.nextLine().toCharArray();
        }
        int pre[][]=new int[n+1][m+1];
        for(int i=0;i<n;i++) {
        	for(int j=m-1;j>=0;j--) {
        		if(a[i][j]=='1')
        			pre[i][j]=(pre[i][j+1]+1);
        		else
        			pre[i][j]=0;
        	}
        }
        long dp[][]=new long[m+1][m+1]; //  idx -- len
        for(int i=0;i<n;i++) {
        	for(int j=0;j<m;j++) {
        		dp[j][pre[i][j]]++;
        	}
        }
        for(int i=0;i<m;i++) {
        	for(int j=m-1;j>0;j--) {
        		dp[i][j]+=dp[i][j+1];
        	}
        }
        long ans=0;
        for(int i=0;i<m;i++) {
        	for(int j=1;j<=m;j++) {
        		ans=Math.max(ans, dp[i][j]*j);
        	}
        }
        pw.println(ans);
        pw.flush();
        pw.close();

    }
    private static void debug(Object... o) {
        System.out.println(Arrays.deepToString(o));
    }
   static class InputReader
        {
        private final InputStream stream;
        private final byte[] buf = new byte[8192];
        private int curChar, snumChars;
        private SpaceCharFilter filter;

        public InputReader(InputStream stream)
        {
            this.stream = stream;
        }
        public int snext()
        {
            if (snumChars == -1)
                throw new InputMismatchException();
            if (curChar >= snumChars)
            {
                curChar = 0;
                try
                {
                    snumChars = stream.read(buf);
                }

                catch (IOException e)
                {
                    throw new InputMismatchException();
                }

                if (snumChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public int nextInt()
        {
            int c = snext();
            while (isSpaceChar(c))
            {
                c = snext();
            }
            int sgn = 1;
            if (c == '-')
            {
                sgn = -1;
                c = snext();
            }
            int res = 0;
            do
            {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public long nextLong()
        {
            int c = snext();
            while (isSpaceChar(c))
            {
                c = snext();
            }
            int sgn = 1;
            if (c == '-')
            {
                sgn = -1;
                c = snext();
            }
            long res = 0;
            do
            {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public int[] nextIntArray(int n)
        {
            int a[] = new int[n];
            for (int i = 0; i < n; i++)
            {
                a[i] = nextInt();
            }
            return a;
        }
        static class tri implements Comparable<tri> {
            int p, c, l;

            tri(int p, int c, int l) {
                this.p = p;
                this.c = c;
                this.l = l;
            }

            public int compareTo(tri o) {
                return Integer.compare(l, o.l);
            }
        }

        public String readString()
        {
            int c = snext();
            while (isSpaceChar(c))
            {
                c = snext();
            }
            StringBuilder res = new StringBuilder();
            do
            {
                res.appendCodePoint(c);
                c = snext();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        public String nextLine()
        {
            int c = snext();
            while (isSpaceChar(c))
                c = snext();
            StringBuilder res = new StringBuilder();
            do
            {
                res.appendCodePoint(c);
                c = snext();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        public boolean isSpaceChar(int c)
        {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c)
        {
            return c == '\n' || c == '\r' || c == -1;
        }

        public interface SpaceCharFilter
        {
            public boolean isSpaceChar(int ch);
        }
    }
   public static long modularExponentiation(long x,long n,long M)
   {
       long result=1;
       while(n>0)
       {
           if(n % 2 ==1)
               result=(result%M * x%M)%M;
           x=(x%M * x%M)%M;
           n=n/2;
       }
       return result;
   }
    static class pair implements Comparable<pair>{
        Integer x;
        Long y;
        Integer z;
        pair(Integer x,long  w,int z){
            this.x=x;
            this.y=w;
            this.z=z;
        }
         public int compareTo(pair o) {
                int result = x.compareTo(o.x);
                if(result==0)
                    result = y.compareTo(o.y);

            return result;
            }
         public String toString(){
            return (x+" "+y);
        }
  }

}


import java.io.*;
import java.util.*;

public class Myclass {
     public static ArrayList a[]=new ArrayList[3000001];
     public static boolean isPrime[]=new boolean [1000001];
     public static Vector<Integer>v=new Vector<>();
     static void pre() {
    	 Arrays.fill(isPrime, true);
    	 isPrime[0]=false;
    	 isPrime[1]=false;
    	 for(int i=2;i*i<=1e6;i++) {
    		 if(isPrime[i]) {
    			 for(int j=2*i;j<=1e6;j+=i) {
    				 isPrime[j]=false;
    			 }
    		 }
    	 }

     }
     public static void main(String[] args) throws FileNotFoundException
    {
    	InputReader in=new InputReader(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        int n=in.nextInt();
        int m=in.nextInt();
        char a[][]=new char[n][m];
        for(int i=0;i<n;i++) {
        	a[i]=in.nextLine().toCharArray();
        }
        int pre[][]=new int[n+1][m+1];
        for(int i=0;i<n;i++) {
        	for(int j=m-1;j>=0;j--) {
        		if(a[i][j]=='1')
        			pre[i][j]=(pre[i][j+1]+1);
        		else
        			pre[i][j]=0;
        	}
        }
        long dp[][]=new long[n][m+1]; //  idx -- len
        for(int i=0;i<n;i++) {
        	for(int j=0;j<m;j++) {
        		dp[j][pre[i][j]]++;
        	}
        }
        for(int i=0;i<m;i++) {
        	for(int j=m-1;j>0;j--) {
        		dp[i][j]+=dp[i][j+1];
        	}
        }
        long ans=0;
        for(int i=0;i<m;i++) {
        	for(int j=1;j<=m;j++) {
        		ans=Math.max(ans, dp[i][j]*j);
        	}
        }
        pw.println(ans);
        pw.flush();
        pw.close();

    }
    private static void debug(Object... o) {
        System.out.println(Arrays.deepToString(o));
    }
   static class InputReader
        {
        private final InputStream stream;
        private final byte[] buf = new byte[8192];
        private int curChar, snumChars;
        private SpaceCharFilter filter;

        public InputReader(InputStream stream)
        {
            this.stream = stream;
        }
        public int snext()
        {
            if (snumChars == -1)
                throw new InputMismatchException();
            if (curChar >= snumChars)
            {
                curChar = 0;
                try
                {
                    snumChars = stream.read(buf);
                }

                catch (IOException e)
                {
                    throw new InputMismatchException();
                }

                if (snumChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public int nextInt()
        {
            int c = snext();
            while (isSpaceChar(c))
            {
                c = snext();
            }
            int sgn = 1;
            if (c == '-')
            {
                sgn = -1;
                c = snext();
            }
            int res = 0;
            do
            {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public long nextLong()
        {
            int c = snext();
            while (isSpaceChar(c))
            {
                c = snext();
            }
            int sgn = 1;
            if (c == '-')
            {
                sgn = -1;
                c = snext();
            }
            long res = 0;
            do
            {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public int[] nextIntArray(int n)
        {
            int a[] = new int[n];
            for (int i = 0; i < n; i++)
            {
                a[i] = nextInt();
            }
            return a;
        }
        static class tri implements Comparable<tri> {
            int p, c, l;

            tri(int p, int c, int l) {
                this.p = p;
                this.c = c;
                this.l = l;
            }

            public int compareTo(tri o) {
                return Integer.compare(l, o.l);
            }
        }

        public String readString()
        {
            int c = snext();
            while (isSpaceChar(c))
            {
                c = snext();
            }
            StringBuilder res = new StringBuilder();
            do
            {
                res.appendCodePoint(c);
                c = snext();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        public String nextLine()
        {
            int c = snext();
            while (isSpaceChar(c))
                c = snext();
            StringBuilder res = new StringBuilder();
            do
            {
                res.appendCodePoint(c);
                c = snext();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        public boolean isSpaceChar(int c)
        {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c)
        {
            return c == '\n' || c == '\r' || c == -1;
        }

        public interface SpaceCharFilter
        {
            public boolean isSpaceChar(int ch);
        }
    }
   public static long modularExponentiation(long x,long n,long M)
   {
       long result=1;
       while(n>0)
       {
           if(n % 2 ==1)
               result=(result%M * x%M)%M;
           x=(x%M * x%M)%M;
           n=n/2;
       }
       return result;
   }
    static class pair implements Comparable<pair>{
        Integer x;
        Long y;
        Integer z;
        pair(Integer x,long  w,int z){
            this.x=x;
            this.y=w;
            this.z=z;
        }
         public int compareTo(pair o) {
                int result = x.compareTo(o.x);
                if(result==0)
                    result = y.compareTo(o.y);

            return result;
            }
         public String toString(){
            return (x+" "+y);
        }
  }

}


import java.io.*;
import java.util.*;

public class maximumsubmatrix2
{
	public static void main(String[] args)
	{
		FastScanner in = new FastScanner();
		int n = in.nextInt();
		int m = in.nextInt();
		char data[][] = new char[n][m];

		for(int i = 0; i < n; i++)
			data[i] = in.next().toCharArray();

		Integer precomp[][] = new Integer[m][n];
		for(int i = 0; i < n; i++)
			precomp[m-1][i] = data[i][m-1] - '0';
		for(int i = 0; i < n; i++)
			for(int j = m-2; j >= 0; j--)
				if(data[i][j] == '1')
					precomp[j][i] = precomp[j+1][i] + (data[i][j] - '0');
				else
					precomp[j][i] = 0;

		int ans = 0;
		for(int i = 0; i < m; i++)
		{
			int radix[] = new int[m+1];
			for(int j = 0; j < n; j++)
				radix[precomp[i][j]]++;

			int pos1 = 0, pos2 = m;
			while(pos1 < n)
			{
				if(radix[pos2] == 0)
					pos2--;
				else
				{
					precomp[i][pos1++] = pos2;
					radix[pos2]--;
				}
			}

			for(int j = 0; j < n; j++)
				ans = Math.max(ans, precomp[i][j] * (j+1));
		}

		System.out.println(ans);
	}

	public static class FastScanner
	{
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(String s)
		{
			try {
				br = new BufferedReader(new FileReader(s));
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		public FastScanner()
		{
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String nextToken()
		{
			while (st == null || !st.hasMoreElements())
			{
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt()
		{
			return Integer.parseInt(nextToken());
		}

		long nextLong()
		{
			return Long.parseLong(nextToken());
		}

		double nextDouble()
		{
			return Double.parseDouble(nextToken());
		}

		String next()
		{
			return nextToken();
		}
	}
}


import java.io.*;
import java.util.*;

public class maximumsubmatrix2
{
	public static void main(String[] args)
	{
		FastScanner in = new FastScanner();
		int n = in.nextInt();
		int m = in.nextInt();
		char data[][] = new char[n][m];

		for(int i = 0; i < n; i++)
			data[i] = in.next().toCharArray();

		int precomp[][] = new int[m][n];
		for(int i = 0; i < n; i++)
			precomp[m-1][i] = data[i][m-1] - '0';
		for(int i = 0; i < n; i++)
			for(int j = m-2; j >= 0; j--)
				if(data[i][j] == '1')
					precomp[j][i] = precomp[j+1][i] + (data[i][j] - '0');
				else
					precomp[j][i] = 0;

		int ans = 0;
		for(int i = 0; i < m; i++)
		{
			int radix[] = new int[m+1];
			for(int j = 0; j < n; j++)
				radix[precomp[i][j]]++;

			int pos1 = 0, pos2 = m;
			while(pos1 < n)
			{
				if(radix[pos2] == 0)
					pos2--;
				else
				{
					precomp[i][pos1++] = pos2;
					radix[pos2]--;
				}
			}

			for(int j = 0; j < n; j++)
				ans = Math.max(ans, precomp[i][j] * (j+1));
		}

		System.out.println(ans);
	}

	public static class FastScanner
	{
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(String s)
		{
			try {
				br = new BufferedReader(new FileReader(s));
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		public FastScanner()
		{
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String nextToken()
		{
			while (st == null || !st.hasMoreElements())
			{
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt()
		{
			return Integer.parseInt(nextToken());
		}

		long nextLong()
		{
			return Long.parseLong(nextToken());
		}

		double nextDouble()
		{
			return Double.parseDouble(nextToken());
		}

		String next()
		{
			return nextToken();
		}
	}
}


import java.io.*;
import java.util.*;

public class maximumsubmatrix2
{
	public static void main(String[] args)
	{
		FastScanner in = new FastScanner();
		int n = in.nextInt();
		int m = in.nextInt();
		char data[][] = new char[n][m];

		for(int i = 0; i < n; i++)
			data[i] = in.next().toCharArray();

		Integer precomp[][] = new Integer[m][n];
		for(int i = 0; i < n; i++)
			precomp[m-1][i] = data[i][m-1] - '0';
		for(int i = 0; i < n; i++)
			for(int j = m-2; j >= 0; j--)
				if(data[i][j] == '1')
					precomp[j][i] = precomp[j+1][i] + (data[i][j] - '0');
				else
					precomp[j][i] = 0;

		int ans = 0;
		for(int i = 0; i < m; i++)
		{
			Arrays.sort(precomp[i], Collections.reverseOrder());

			for(int j = 0; j < n; j++)
				ans = Math.max(ans, precomp[i][j] * (j+1));
		}

		System.out.println(ans);
	}

	public static class FastScanner
	{
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(String s)
		{
			try {
				br = new BufferedReader(new FileReader(s));
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		public FastScanner()
		{
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String nextToken()
		{
			while (st == null || !st.hasMoreElements())
			{
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt()
		{
			return Integer.parseInt(nextToken());
		}

		long nextLong()
		{
			return Long.parseLong(nextToken());
		}

		double nextDouble()
		{
			return Double.parseDouble(nextToken());
		}

		String next()
		{
			return nextToken();
		}
	}
}


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Parser in = new Parser(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskB solver = new TaskB();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskB {
    int n, m;
    int[][] right;
    String[] matrix;

    public void solve(int testNumber, Parser in, OutputWriter out) {
        n = in.nextInt();
        m = in.nextInt();

        matrix = new String[n];
        right = new int[n][m];

        int ans = 0;

        for (int i = 0; i < n; i++) {
            matrix[i] = in.next();
            int last = 0;
            for (int j = 0; j < m; j++) {
                if (matrix[i].charAt(j) == '0') {
                    while (last <= j) {
                        right[i][last] = j-last;
                        last++;
                    }
                }
            }

            while (last <= m-1) {
                right[i][last] = m-last;
                last++;
            }
        }

        int[] count = new int[m+2];
        for (int j = 0; j < m; j++) {
            Arrays.fill(count, 0);
            for (int i = 0; i < n; i++) {
                count[right[i][j]]++;
            }

            int tot = 0;
            for (int i = m; i >= 0; i--) {
                tot += count[i];
                ans = Math.max(ans, i * tot);
            }
        }

        out.println(ans);
    }
}

class Parser
{
    private BufferedReader din;
    private StringTokenizer tokenizer;

    public Parser(InputStream in)
    {
        din = new BufferedReader(new InputStreamReader(in));
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(din.readLine());
            } catch (Exception e) {
                throw new UnknownError();
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt()
    {
        return Integer.parseInt(next());
    }

    }

class OutputWriter extends PrintWriter {
    public OutputWriter(Writer out) {
        super(out);
    }

    public OutputWriter(OutputStream out) {
        super(out);
    }

    }


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

public class Main {
	static int n,m;
	static Node[][] matrix;
	public static void main(String[] args) throws IOException {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer(br.readLine());
		int n=Integer.parseInt(st.nextToken());
		int m=Integer.parseInt(st.nextToken());
		matrix=new Node[n][m];
		for (int i = 0; i < n; i++) {
			String linea=br.readLine();
			for (int j = 0; j < m; j++) {
				matrix[i][j]=new Node(linea.charAt(j));
			}
		}
		for (int i = 0; i < n; i++) {
			for (int j = m-1; j >=0 ; j--) {
				if (matrix[i][j].v=='1'){
					matrix[i][j].right=1;
					if (j!=m-1)
					matrix[i][j].right+=matrix[i][j+1].right;
				}
			}
		}
		long res=0;
		for (int j = 0; j < m; j++) {
			ArrayList<Node> column=new ArrayList<Node>(n);
			for (int i = 0; i < n; i++) {
				column.add(matrix[i][j]);
			}
			Collections.sort(column);
			for (int i = 0; i < n; i++) {
				long area=(i+1)*column.get(i).right;
				res=Math.max(res,area);
			}
		}
		System.out.println(res);
	}
}
class Node implements Comparable<Node>{
	char v;
	int right;
	public Node(char v){
		this.v=v;right=0;
	}
	@Override
	public int compareTo(Node o) {
		return -1*Integer.compare(right, o.right);
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

public class Main {
	static int n,m;
	static Node[][] matrix;
	public static void main(String[] args) throws IOException {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer(br.readLine());
		int n=Integer.parseInt(st.nextToken());
		int m=Integer.parseInt(st.nextToken());
		matrix=new Node[n][m];
		for (int i = 0; i < n; i++) {
			String linea=br.readLine();
			for (int j = 0; j < m; j++) {
				matrix[i][j]=new Node(linea.charAt(j));
			}
		}
		for (int i = 0; i < n; i++) {
			for (int j = m-2; j >=0 ; j--) {
				if (matrix[i][j].v=='1'){
					matrix[i][j].right=matrix[i][j+1].right+1;
				}
			}
		}
		long res=0;
		for (int j = 0; j < m; j++) {
			ArrayList<Node> column=new ArrayList<Node>(n);
			for (int i = 0; i < n; i++) {
				column.add(matrix[i][j]);
			}
			Collections.sort(column);
			for (int i = 0; i < n; i++) {
				long area=(i+1)*column.get(i).right;
				res=Math.max(res,area);
			}
		}
		System.out.println(res);
	}
}
class Node implements Comparable<Node>{
	char v;
	int right;
	public Node(char v){
		this.v=v;right=0;
	}
	@Override
	public int compareTo(Node o) {
		return -1*Integer.compare(right, o.right);
	}
}


// ONE DAY, YOU WILL BE BEYOND THE REACH OF SPACE AND TIME. //
// UNTIL THEN, STAY LOW AND CODE HARD. //
// Author :- Saurabh//
//BIT MESRA, RANCHI//
import java.io.*;
import java.util.*;
import static java.lang.Math.*;
public class maximumSubmatrix {

    static void Bolo_Jai_Mata_Di() {

        n = ni();m=ni();
        char ch[][]=new char[n][];

        tsc();

        for(int i=0;i<n;i++)ch[i]=ns().toCharArray();
        int dp[]=new int[5005];long ans=0;

        for(int j=0;j<m;j++){
            int ar[]=new int[5005];
            for(int i=0;i<n;i++)
            {
                if(ch[i][j]=='1'){
                    dp[i]++;
                    ar[dp[i]]++;
                }
                else dp[i]=0;
            }
            for(int i=m;i>=0;i--){
                ar[i]+=ar[i+1];
                ans=max(ans,ar[i]*i);
            }
        }
        pl(ans);
        flush();
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //THE DON'T CARE ZONE BEGINS HERE...//

    static Calendar ts, te;                                                  //For time calculation
    static int mod9 = 1000000007;
    static int n, m, k, t, mod = 998244353;
    static Lelo input = new Lelo(System.in);
    static PrintWriter pw = new PrintWriter(System.out, true);

    public static void main(String[] args) {      //threading has been used to increase the stack size.

        new Thread(null, null, "BlackRise", 1 << 25)  //the last parameter is stack size desired.,
        {
            public void run() {

                try {

                    Bolo_Jai_Mata_Di();
                } catch (Exception e) {
                    e.printStackTrace();
                    System.exit(1);
                }
            }
        }.start();
    }

    static class Lelo {                                              //Lelo class for fast input
        private InputStream ayega;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private SpaceCharFilter filter;

        public Lelo(InputStream ayega) {
            this.ayega = ayega;
        }

        public int read() {
            if (numChars == -1)
                throw new InputMismatchException();

            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = ayega.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }

                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public String nextLine() {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        public int nextInt() {
            int c = read();

            while (isSpaceChar(c))
                c = read();

            int sgn = 1;

            if (c == '-') {
                sgn = -1;
                c = read();
            }

            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));

            return res * sgn;
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;

            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));
            return res * sgn;
        }

        public double nextDouble() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            double res = 0;
            while (!isSpaceChar(c) && c != '.') {
                if (c == 'e' || c == 'E')
                    return res * Math.pow(10, nextInt());
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            if (c == '.') {
                c = read();
                double m = 1;
                while (!isSpaceChar(c)) {
                    if (c == 'e' || c == 'E')
                        return res * Math.pow(10, nextInt());
                    if (c < '0' || c > '9')
                        throw new InputMismatchException();
                    m /= 10;
                    res += (c - '0') * m;
                    c = read();
                }
            }
            return res * sgn;
        }

        public String readString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            }
            while (!isSpaceChar(c));

            return res.toString();
        }

        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public String next() {
            return readString();
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }

    // functions to take input//
    static int ni() {
        return input.nextInt();
    }

    static long nl() {
        return input.nextLong();
    }

    static double nd() {
        return input.nextDouble();
    }

    static String ns() {
        return input.readString();
    }

    //functions to give output
    static void pl() {
        pw.println();
    }

    static void p(Object o) {
        pw.print(o + " ");
    }

    static void pws(Object o) {
        pw.print(o + "");
    }

    static void pl(Object o) {
        pw.println(o);
    }

    static void tsc()                                          //calculates the starting time of execution
    {
        ts = Calendar.getInstance();
        ts.setTime(new Date());
    }

    static void tec()                                          //calculates the ending time of execution
    {
        te = Calendar.getInstance();
        te.setTime(new Date());
    }

    static void pwt()                                          //prints the time taken for execution
    {
        pw.printf("\nExecution time was :- %f s\n", (te.getTimeInMillis() - ts.getTimeInMillis()) / 1000.00);
    }
    static void sort(int ar[], int n) {
        for (int i = 0; i < n; i++) {
            int ran = (int) (Math.random() * n);
            int temp = ar[i];
            ar[i] = ar[ran];
            ar[ran] = temp;
        }
        Arrays.sort(ar);
    }

    static void sort(long ar[], int n) {
        for (int i = 0; i < n; i++) {
            int ran = (int) (Math.random() * n);
            long temp = ar[i];
            ar[i] = ar[ran];
            ar[ran] = temp;
        }
        Arrays.sort(ar);
    }

    static void sort(char ar[], int n) {
        for (int i = 0; i < n; i++) {
            int ran = (int) (Math.random() * n);
            char temp = ar[i];
            ar[i] = ar[ran];
            ar[ran] = temp;
        }
        Arrays.sort(ar);
    }
    static void flush() {
        tec();                  //ending time of execution
        //pwt();                //prints the time taken to execute the program
        pw.flush();
        pw.close();
    }
}


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class D221 {
	public static void main(String[] args) {
		FS scan = new FS(System.in);
		int R = scan.nextInt(), C = scan.nextInt();

		int[][] mat = new int[R][C];
		int[][] right = new int[R][C];
		for(int i=0;i<R;i++){
			String line = scan.next();
			for(int j=0;j<C;j++){
				mat[i][j] = (line.charAt(j)=='1')?1:0;
			}
		}

		for(int i=0;i<R;i++){
			int start = 0;
			while(start<C){
				while(start<C&&mat[i][start]==0)start++;
				if(start>=C)break;
				int r = start;
				while(r<C-1&&mat[i][r+1]==1)r++;
				int count = r-start+1;
				for(int j=start;j<=r;j++)right[i][j]=count--;
				start = r+1;
			}
		}
		int max = 0;
		for(int i=0;i<C;i++){
			int[] count = new int[C+1];
			for(int j=0;j<R;j++)count[right[j][i]]++;
			int idx = 0;
			for(int j=C;j>0;j--)
				if(count[j]>0)
					for(int k=0;k<count[j];k++)
						max = Math.max(max, (++idx)*j);

		}
		System.out.println(max);
	}

	private static class FS {
		BufferedReader br;
		StringTokenizer st;
		public FS(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

		public String next() {
			while(st==null||!st.hasMoreElements()){
				try{st = new StringTokenizer(br.readLine());}
				catch(Exception e) {}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}
		public long nextLong() {
			return Long.parseLong(next());
		}
	}
}


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class D221 {
	public static void main(String[] args) {
		FS scan = new FS(System.in);
		int R = scan.nextInt(), C = scan.nextInt();

		int[][] mat = new int[R][C];
		int[][] sum = new int[R][C+1];
		for(int i=0;i<R;i++){
			String line = scan.next();
			for(int j=0;j<C;j++){
				mat[i][j] = (line.charAt(j)=='1')?1:0;
				sum[i][j+1] = sum[i][j]+mat[i][j];
			}
		}

		int max = 0;
		for(int i=0;i<C;i++){
			int prev = R;
			ArrayList<Integer> list = new ArrayList<>();
			for(int j=0;j<R;j++)list.add(j);
			for(int j=i;j<C;j++){
				int count = 0;
				if(prev*(j-i+1)<=max)continue;
				for(int z=0;z<list.size();z++){
					int k = list.get(z);
					int s = sum[k][j+1]-sum[k][i];
					if(s==(j-i+1))count++;
					else list.remove(z--);
				}
				max = (max<count*(j-i+1))?count*(j-i+1):max;
				prev=count;
			}
		}
		System.out.println(max);
	}

	private static class FS {
		BufferedReader br;
		StringTokenizer st;
		public FS(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

		public String next() {
			while(st==null||!st.hasMoreElements()){
				try{st = new StringTokenizer(br.readLine());}
				catch(Exception e) {}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}
		public long nextLong() {
			return Long.parseLong(next());
		}
	}
}


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class D221 {
	public static void main(String[] args) {
		FS scan = new FS(System.in);
		int R = scan.nextInt(), C = scan.nextInt();

		int[][] mat = new int[R][C];
		int[][] right = new int[R][C];
		for(int i=0;i<R;i++){
			String line = scan.next();
			for(int j=0;j<C;j++){
				mat[i][j] = (line.charAt(j)=='1')?1:0;
			}
		}

		for(int i=0;i<R;i++){
			int start = 0;
			while(start<C){
				while(start<C&&mat[i][start]==0)start++;
				if(start>=C)break;
				int r = start;
				while(r<C-1&&mat[i][r+1]==1)r++;
				int count = r-start+1;
				for(int j=start;j<=r;j++)right[i][j]=count--;
				start = r+1;
			}
		}
		int max = 0;
		for(int i=0;i<C;i++){
			int[] count = new int[C+1];
			for(int j=0;j<R;j++)count[right[j][i]]++;
			ArrayList<Integer> temp = new ArrayList<>();
			for(int j=C;j>0;j--)
				if(count[j]>0)
					for(int k=0;k<count[j];k++)
						temp.add(j);
			for(int j=0;j<temp.size();j++){
				max = Math.max(max, (j+1)*(temp.get(j)));
			}
		}
		System.out.println(max);
	}

	private static class FS {
		BufferedReader br;
		StringTokenizer st;
		public FS(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

		public String next() {
			while(st==null||!st.hasMoreElements()){
				try{st = new StringTokenizer(br.readLine());}
				catch(Exception e) {}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}
		public long nextLong() {
			return Long.parseLong(next());
		}
	}
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class D221 {
	public static void main(String[] args) throws FileNotFoundException {
		FS scan = new FS(System.in);
		//FS scan = new FS(new FileInputStream(new File("test.in")));
		int R = scan.nextInt(), C = scan.nextInt();

		char[][] mat = new char[R][C];
		int[][] right = new int[R][C];
		for(int i=0;i<R;i++){
			String line = scan.next();
			mat[i] = line.toCharArray();
		}
		long t1 = System.nanoTime();

		for(int i=0;i<R;i++){
			int start = 0;
			while(start<C){
				while(start<C&&mat[i][start]=='0')start++;
				if(start>=C)break;
				int r = start;
				while(r<C-1&&mat[i][r+1]=='1')r++;
				int count = r-start+1;
				for(int j=start;j<=r;j++)right[i][j]=count--;
				start = r+1;
			}
		}
		//System.out.println((System.nanoTime()-t1)/1000000);
		t1 = System.nanoTime();
		int max = 0;
		int[][] count = new int[C][C+1];
		for(int i=0;i<C;i++){

			for(int j=0;j<R;j++)count[i][right[j][i]]++;
			int idx = 0;
			for(int j=C;j>0;j--)
				if(count[i][j]>0)
					for(int k=0;k<count[i][j];k++)
						max = Math.max(max, (++idx)*j);

		}
		//System.out.println((System.nanoTime()-t1)/1000000);
		System.out.println(max);
	}

	private static class FS {
		BufferedReader br;
		StringTokenizer st;
		public FS(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

		public String next() {
			while(st==null||!st.hasMoreElements()){
				try{st = new StringTokenizer(br.readLine());}
				catch(Exception e) {}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}
		public long nextLong() {
			return Long.parseLong(next());
		}
	}
}


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class D221 {
	public static void main(String[] args) {
		FS scan = new FS(System.in);
		int R = scan.nextInt(), C = scan.nextInt();

		int[][] mat = new int[R][C];
		int[][] sum = new int[R][C+1];
		for(int i=0;i<R;i++){
			String line = scan.next();
			for(int j=0;j<C;j++){
				mat[i][j] = (line.charAt(j)=='1')?1:0;
				sum[i][j+1] = sum[i][j]+mat[i][j];
			}
		}

		int max = 0;
		for(int i=0;i<C;i++){
			int prev = R;
			for(int j=i;j<C;j++){
				int count = 0;
				if(prev*(j-i+1)<=max)continue;
				for(int k=0;k<R;k++){
					int s = sum[k][j+1]-sum[k][i];
					if(s==(j-i+1))count++;
				}
				max = (max<count*(j-i+1))?count*(j-i+1):max;
				prev=count;
			}
		}
		System.out.println(max);
	}

	private static class FS {
		BufferedReader br;
		StringTokenizer st;
		public FS(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

		public String next() {
			while(st==null||!st.hasMoreElements()){
				try{st = new StringTokenizer(br.readLine());}
				catch(Exception e) {}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}
		public long nextLong() {
			return Long.parseLong(next());
		}
	}
}


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class D221 {
	public static void main(String[] args) {
		FS scan = new FS(System.in);
		int R = scan.nextInt(), C = scan.nextInt();

		int[][] mat = new int[R][C];
		int[][] right = new int[R][C];
		for(int i=0;i<R;i++){
			String line = scan.next();
			for(int j=0;j<C;j++){
				mat[i][j] = (line.charAt(j)=='1')?1:0;
			}
		}

		for(int i=0;i<R;i++){
			int start = 0;
			while(start<C){
				while(start<C&&mat[i][start]==0)start++;
				if(start>=C)break;
				int r = start;
				while(r<C-1&&mat[i][r+1]==1)r++;
				int count = r-start+1;
				for(int j=start;j<=r;j++)right[i][j]=count--;
				start = r+1;
			}
		}
		int max = 0;
		for(int i=0;i<C;i++){
			int[] count = new int[C+1];
			for(int j=0;j<R;j++)count[right[j][i]]++;
			ArrayList<Integer> temp = new ArrayList<>();
			for(int j=C;j>=0;j--)
				if(count[j]>0)
					for(int k=0;k<count[j];k++)
						temp.add(j);
			for(int j=0;j<temp.size();j++){
				max = Math.max(max, (j+1)*(temp.get(j)));
			}
		}
		System.out.println(max);
	}

	private static class FS {
		BufferedReader br;
		StringTokenizer st;
		public FS(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

		public String next() {
			while(st==null||!st.hasMoreElements()){
				try{st = new StringTokenizer(br.readLine());}
				catch(Exception e) {}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}
		public long nextLong() {
			return Long.parseLong(next());
		}
	}
}


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class D221 {
	public static void main(String[] args) {
		FS scan = new FS(System.in);
		int R = scan.nextInt(), C = scan.nextInt();

		ST st = new ST(new int[2*C]);
		int[][] mat = new int[R][C];
		for(int i=0;i<R;i++){
			String line = scan.next();
			for(int j=0;j<C;j++){
				mat[i][j] = (line.charAt(j)=='1')?1:0;
			}
		}
		for(int i=0;i<R;i++){
			int start = 0;
			for(int j=0;j<C;j++){
				if(mat[i][j]==1){
					start=j;
					break;
				}
			}
			for(int j=start;j<C;j++){
				if(mat[i][j]==0){
					st.update(2*start, 2*(j-1), 1);
					while(j<C-1&&mat[i][j+1]==0)j++;
					start=j+1;
					continue;
				}
			}
			if(start!=C)st.update(2*start, 2*(C-1), 1);
		}

		int max = 0;
		for(int i=0;i<C;i++){
			for(int j=i;j<C;j++){
				max = Math.max(max, st.query(2*i, 2*j)*(j-i+1));
			}
		}
		System.out.println(max);
	}

	public static class ST {
		static final int oo = 2000000000;
		int[] val, delta;
		int K;
		public ST(int[] list) {
			K = (int)Math.ceil(Math.log(list.length)/Math.log(2));
			val = new int[4*list.length];
			delta = new int[4*list.length];
			build(list, 0, (1<<K)-1, 1);
		}
		private int build(int[] list, int L, int R, int idx) {
			if(L==R) {
				if(L>=list.length)return oo;
				return val[idx] = list[L];
			}
			int mid = R+L>>1;
			return val[idx] = Math.min(build(list,L,mid,idx<<1), build(list,mid+1,R,(idx<<1)+1));
		}

		public int query(int L, int R) { return query(L,R,0,(1<<K)-1,1); }
		public int query(int L, int R, int tL, int tR, int idx) {
			if(tL<L&&tR<L||tL>R&&tR>R)return oo;
			if(L<=tL&&tR<=R){
				return val[idx];
			}
			prop(tL,tR,idx);
			int mid = tL+tR>>1;
			return Math.min(query(L,R,tL,mid,idx<<1), query(L,R,mid+1,tR,(idx<<1)+1));
		}
		public void update(int L, int R, int V){update(L,R,0,(1<<K)-1,1,V);}
		public int update(int L, int R, int tL, int tR, int idx, int V) {
			if(tL<L&&tR<L||tL>R&&tR>R)return val[idx];
			if(L<=tL&&tR<=R){
				val[idx]+=V;
				if(tL!=tR)delta[idx]+=V;
				return val[idx];
			}
			prop(tL,tR,idx);
			int mid = tL+tR>>1;
			return val[idx] = Math.min(update(L,R,tL,mid,idx<<1,V), update(L,R,mid+1,tR,(idx<<1)+1,V));
		}

		public void prop(int L, int R, int idx) {
			if(idx>=val.length)return;
			if(delta[idx]==0)return;
			int d = delta[idx];
			delta[idx] = 0;
			int mid = R+L>>1;
			update(L,mid,L,mid,idx<<1,d);
			update(mid+1,R,mid+1,R,(idx<<1)+1,d);
		}
	}
	private static class FS {
		BufferedReader br;
		StringTokenizer st;
		public FS(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

		public String next() {
			while(st==null||!st.hasMoreElements()){
				try{st = new StringTokenizer(br.readLine());}
				catch(Exception e) {}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}
		public long nextLong() {
			return Long.parseLong(next());
		}
	}
}


import java.io.*;
import java.lang.reflect.Array;
import java.util.*;

/**
 * Created by yusuf on 21/03/17.
 */
public class Main {
    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        Solver solver = new Solver();
        solver.solve(in, out);
        out.close();
    }

    static class Solver {
        public void solve(InputReader in, PrintWriter out) {
            int n = in.nextInt(), m = in.nextInt();
            String[] g = new String[n];
            int[][] cnt = new int[n][m];
            for (int i = 0; i < n; ++i) {
                g[i] = in.next();
                for (int j = m - 1, tmp = 0; j >= 0; --j) {
                    tmp = (g[i].charAt(j) == '0') ? 0 : tmp + 1;
                    cnt[i][j] = tmp;
                }
            }
            int[] colCnt = new int[n];
            int ans = 0;
            for (int j = 0; j < m; j++) {
                for (int i = 0; i < n; i++) {
                    colCnt[i] = cnt[i][j];
                }
                Arrays.sort(colCnt);
                for (int i = n - 1; i >= 0; --i) {
                    ans = Math.max(ans, (n - i) * colCnt[i]);
                }
            }
            out.println(ans);
        }
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.*;
import java.lang.reflect.Array;
import java.util.*;

/**
 * Created by yusuf on 21/03/17.
 */
public class Main {
    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        Solver solver = new Solver();
        solver.solve(in, out);
        out.close();
    }
}

class Solver {

    void solve(InputReader in, PrintWriter out) {
        int n = in.nextInt(), m = in.nextInt();
        String[] g = new String[n];
        int[][] cnt = new int[n][m];
        for (int i = 0; i < n; ++i) {
            g[i] = in.next();
            for (int j = m - 1, tmp = 0; j >= 0; --j) {
                tmp = (g[i].charAt(j) == '0') ? 0 : tmp + 1;
                cnt[i][j] = tmp;
            }
        }
        Integer[] colCnt = new Integer[n];
        int ans = 0;
        for (int j = 0; j < m; j++) {
            for (int i = 0; i < n; i++) {
                colCnt[i] = cnt[i][j];
            }
            Arrays.sort(colCnt, Collections.reverseOrder());
            for (int i = 0; i < n; ++i) {
                ans = Math.max(ans, (i + 1) * colCnt[i]);
            }
        }
        out.println(ans);
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}


import java.util.*;
import java.lang.*;
import java.math.*;
import java.io.*;

/* spar5h */

public class cf4 implements Runnable{

	final static long mod = (long)1e9 + 7;

	public void run() {

		InputReader s = new InputReader(System.in);
		PrintWriter w = new PrintWriter(System.out);

		int n = s.nextInt(), m = s.nextInt();

		char[][] a = new char[n][];

		for(int i = 0; i < n; i++)
			a[i] = s.next().toCharArray();

		int[][] suf = new int[n][m];

		for(int i = 0; i < n; i++)
			suf[i][0] = a[i][0] - '0';

		for(int i = 0; i < n; i++) {

			for(int j = 1; j < m; j++) {

				if(a[i][j] == '1')
					suf[i][j] = suf[i][j - 1] + 1;
				else
					suf[i][j] = 0;
			}
		}

		int[][] freq = new int[m][m + 1];

		for(int j = 0; j < m; j++)
			for(int i = 0; i < n; i++)
				freq[j][suf[i][j]]++;

		for(int i = 0; i < m; i++)
			for(int j = m - 1; j >= 0; j--)
				freq[i][j] += freq[i][j + 1];

		int res = 0;

		for(int i = 0; i < m; i++)
			for(int j = 1; j <= m; j++)
				res = Math.max(res, j * freq[i][j]);

		w.println(res);

		w.close();
	}

	static class InputReader {

		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream)
		{
			this.stream = stream;
		}

		public int read()
		{
			if (numChars==-1)
				throw new InputMismatchException();

			if (curChar >= numChars)
			{
				curChar = 0;
				try
				{
					numChars = stream.read(buf);
				}
				catch (IOException e)
				{
					throw new InputMismatchException();
				}

				if(numChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public String nextLine()
		{
			BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
			String str = "";
        try
        {
            str = br.readLine();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return str;
	}
	public int nextInt()
	{
		int c = read();

		while(isSpaceChar(c))
			c = read();

		int sgn = 1;

		if (c == '-')
		{
			sgn = -1;
			c = read();
		}

		int res = 0;
		do
		{
			if(c<'0'||c>'9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		}
		while (!isSpaceChar(c));

		return res * sgn;
	}

	public long nextLong()
	{
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-')
		{
			sgn = -1;
			c = read();
		}
		long res = 0;

		do
		{
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		}
		while (!isSpaceChar(c));
			return res * sgn;
	}

	public double nextDouble()
	{
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-')
		{
			sgn = -1;
			c = read();
		}
		double res = 0;
		while (!isSpaceChar(c) && c != '.')
		{
			if (c == 'e' || c == 'E')
				return res * Math.pow(10, nextInt());
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		}
		if (c == '.')
		{
			c = read();
			double m = 1;
			while (!isSpaceChar(c))
			{
				if (c == 'e' || c == 'E')
					return res * Math.pow(10, nextInt());
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				m /= 10;
				res += (c - '0') * m;
				c = read();
			}
		}
		return res * sgn;
	}

	public String readString()
	{
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do
		{
			res.appendCodePoint(c);
			c = read();
		}
		while (!isSpaceChar(c));

		return res.toString();
	}

	public boolean isSpaceChar(int c)
	{
		if (filter != null)
			return filter.isSpaceChar(c);
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	public String next()
	{
		return readString();
	}

	public interface SpaceCharFilter
	{
		public boolean isSpaceChar(int ch);
	}
}

public static void main(String args[]) throws Exception
{
	new Thread(null, new cf4(),"cf4",1<<26).start();
	}
}


import java.io.*;
import java.util.*;

public class B implements Runnable{
	public static void main (String[] args) {new Thread(null, new B(), "_cf", 1 << 28).start();}

	public void run() {
		FastScanner fs = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		System.err.println("Go!");

		int n = fs.nextInt();
		int m = fs.nextInt();
		int[][] a = new int[n][m];
		for(int i = 0; i < n; i++) {
			char[] str = fs.next().toCharArray();
			for(int j = 0; j < m; j++)
				a[i][j] = str[j]-'0';
		}
		int[] best = new int[n];
		int res = 0;
		int[] freq = new int[m + 1];
		int[] sums = new int[m + 1];
		for(int j = m - 1; j >= 0; j--) {
			int[] nbest = new int[n];
			Arrays.fill(freq, 0); Arrays.fill(sums, 0);
			for(int i = 0; i < n; i++) {
				if(a[i][j] != 0) {
					nbest[i] = 1 + best[i];
				}
				freq[nbest[i]]++;
			}
			int add = 0;
			for(int i = m; i > 0; i--) {
				sums[i] = add + freq[i];
				res = Math.max(res, i * sums[i]);
				add += freq[i];
			}
			best = nbest;
		}
		out.println(res);
		out.close();
	}

	void sort (int[] a) {
		int n = a.length;
		for(int i = 0; i < 50; i++) {
			Random r = new Random();
			int x = r.nextInt(n), y = r.nextInt(n);
			int temp = a[x];
			a[x] = a[y];
			a[y] = temp;
		}
		Arrays.sort(a);
	}

	class FastScanner {
		public int BS = 1<<16;
		public char NC = (char)0;
		byte[] buf = new byte[BS];
		int bId = 0, size = 0;
		char c = NC;
		double num = 1;
		BufferedInputStream in;

		public FastScanner() {
			in = new BufferedInputStream(System.in, BS);
		}

		public FastScanner(String s) throws FileNotFoundException {
			in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
		}

		public char nextChar(){
			while(bId==size) {
				try {
					size = in.read(buf);
				}catch(Exception e) {
					return NC;
				}
				if(size==-1)return NC;
				bId=0;
			}
			return (char)buf[bId++];
		}

		public int nextInt() {
			return (int)nextLong();
		}

		public long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

		public double nextDouble() {
			double cur = nextLong();
			return c!='.' ? cur:cur+nextLong()/num;
		}

		public String next() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c>32) {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c!='\n') {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}

		public int[] nextIntArray(int n) {
			int[] res = new int[n];
			for(int i = 0; i < n; i++) res[i] = nextInt();
			return res;
		}

	}

}


import java.io.*;
import java.util.*;

public class B implements Runnable{
	public static void main (String[] args) {new Thread(null, new B(), "_cf", 1 << 28).start();}

	public void run() {
		FastScanner fs = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		System.err.println("Go!");

		int n = fs.nextInt();
		int m = fs.nextInt();
		int[][] a = new int[n][m];
		for(int i = 0; i < n; i++) {
			char[] str = fs.next().toCharArray();
			for(int j = 0; j < m; j++)
				a[i][j] = str[j]-'0';
		}
		int[][] best = new int[n][m];
		int res = 0;
		for(int j = m - 1; j >= 0; j--) {
			int[] freq = new int[m + 1];
			int[] sums = new int[m + 1];
			for(int i = 0; i < n; i++) {
				if(a[i][j] != 0) {
					best[i][j] = 1 + (j + 1 < m ? best[i][j+1] : 0);
				}
				freq[best[i][j]]++;
			}
			int add = 0;
			for(int i = m; i > 0; i--) {
				sums[i] = add + freq[i];
				res = Math.max(res, i * sums[i]);
				add += freq[i];
			}
		}
		out.println(res);
		out.close();
	}

	void sort (int[] a) {
		int n = a.length;
		for(int i = 0; i < 50; i++) {
			Random r = new Random();
			int x = r.nextInt(n), y = r.nextInt(n);
			int temp = a[x];
			a[x] = a[y];
			a[y] = temp;
		}
		Arrays.sort(a);
	}

	class FastScanner {
		public int BS = 1<<16;
		public char NC = (char)0;
		byte[] buf = new byte[BS];
		int bId = 0, size = 0;
		char c = NC;
		double num = 1;
		BufferedInputStream in;

		public FastScanner() {
			in = new BufferedInputStream(System.in, BS);
		}

		public FastScanner(String s) throws FileNotFoundException {
			in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
		}

		public char nextChar(){
			while(bId==size) {
				try {
					size = in.read(buf);
				}catch(Exception e) {
					return NC;
				}
				if(size==-1)return NC;
				bId=0;
			}
			return (char)buf[bId++];
		}

		public int nextInt() {
			return (int)nextLong();
		}

		public long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

		public double nextDouble() {
			double cur = nextLong();
			return c!='.' ? cur:cur+nextLong()/num;
		}

		public String next() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c>32) {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c!='\n') {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}

		public int[] nextIntArray(int n) {
			int[] res = new int[n];
			for(int i = 0; i < n; i++) res[i] = nextInt();
			return res;
		}

	}

}