func findMaxForm(strs []string, m int, n int) int {
    // return func1(strs, m, n);
    return func2(strs, m, n);
}
// O(len*m*n) time, 2*O(m*n) space
func func1(strs []string, m int, n int) int {
    dp1 := make([][]int, m+1);
    dp2 := make([][]int, m+1);
    for i := 0; i < m+1; i++ {
        dp1[i] = make([]int, n+1);
        dp2[i] = make([]int, n+1);
    }
    for i := 1; i <= len(strs); i++ {
        cnt0, cnt1 := count01(strs[i-1]);
        for j0 := cnt0; j0 <= m; j0++ {
            for j1 := cnt1; j1 <= n; j1++ {
                dp2[j0][j1] = max(dp1[j0][j1], 1 + dp1[j0-cnt0][j1-cnt1]);
            }
        }
        for j0 := 0; j0 <= m; j0++ {
            for j1 := 0; j1 <= n; j1++ {
                dp1[j0][j1] = dp2[j0][j1];
            }
        }
    }
    return dp2[m][n];
}
// O(len*m*n) time, O(m*n) space
func func2(strs []string, m int, n int) int {
    dp1 := make([][]int, m+1);
    for i := 0; i < m+1; i++ {
        dp1[i] = make([]int, n+1);
    }
    for i := 1; i <= len(strs); i++ {
        cnt0, cnt1 := count01(strs[i-1]);
        for j0 := m; j0 >= cnt0; j0-- {
            for j1 := n; j1 >= cnt1; j1-- {
                dp1[j0][j1] = max(dp1[j0][j1], 1 + dp1[j0-cnt0][j1-cnt1]);
            }
        }
    }
    return dp1[m][n];
}
func count01(str string) (int, int) {
    cnt0 := 0;
    cnt1 := 0;
    for _, s := range str {
        if s == '0' {
            cnt0++;
        }
        if s == '1' {
            cnt1++;
        }
    }
    return cnt0, cnt1;
}
func max(a int, b int) int {
    if a > b {
        return a;
    }
    return b;
}