Problem p01104 (C++) — buggy submission, verdict: Runtime Error

#include <iostream>
using namespace std;
int dp[1 << 23], dpn[1 << 23];

int main(void) {
  for (;;) {
    int n, m;
    cin >> n >> m;
    if (n == 0 && m == 0) {
      return 0;
    }
    int b[n][m];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        char c;
        cin >> c;
        if (c == '1') {
          b[i][j] = 1;
        } else {
          b[i][j] = 0;
        }
      }
    }
    if (n < m) { /* nが小さい場合: 総当たりで行く */
      int use[m];
      int max = -1;
      for (int bi = 0; bi < (1 << n); bi++) {
        int kind = 0;
        for (int j = 0; j < m; j++) {
          use[j] = 0;
        }
        for (int i = 0; i < n; i++) {
          if ((bi & (1 << i)) != 0) {
            kind++;
            for (int j = 0; j < m; j++) {
              if (b[i][j] == 1) {
                use[j] = use[j] + 1;
              }
            }
          }
        }
        if (kind > max) {
          bool ok = true;
          for (int j = 0; j < m; j++) {
            if (use[j] % 2 == 1) {
              ok = false;
            }
          }
          if (ok) {
            max = kind;
          }
        }
      }
      cout << max << endl;
    } else { /* mが小さい場合: 各材料が余っているか否かでbit-dp */
      for (int bj = 0; bj < (1 << m); bj++) {
        dp[bj] = -1;
      }
      dp[0] = 0;
      for (int i = 0; i < n; i++) {
        int buse = 0;
        for (int j = 0; j < m; j++) {
          buse = buse * 2 + b[i][j];
        }
        for (int bj = 0; bj < (1 << m); bj++) {
          dpn[bj] = dp[bj];
        }
        for (int bj = 0; bj < (1 << m); bj++) {
          if (dp[bj] != -1 && dp[bj] + 1 > dp[bj ^ buse]) {
            dpn[bj ^ buse] = dp[bj] + 1;
          }
        }
        for (int bj = 0; bj < (1 << m); bj++) {
          dp[bj] = dpn[bj];
        }
      }
      cout << dp[0] << endl;
    }
  }
}


Error: 0

Fixed submission:

#include <iostream>
#define N 21
using namespace std;

int main(void) {
  for (;;) {
    int n, m;
    cin >> n >> m;
    if (n == 0 && m == 0) {
      return 0;
    }
    int b[n][m];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        char c;
        cin >> c;
        if (c == '1') {
          b[i][j] = 1;
        } else {
          b[i][j] = 0;
        }
      }
    }
    if (n < N) { /* nが小さい場合: 総当たりで行く */
      int use[m];
      int max = -1;
      for (int bi = 0; bi < (1 << N); bi++) {
        int kind = 0;
        for (int j = 0; j < m; j++) {
          use[j] = 0;
        }
        for (int i = 0; i < n; i++) {
          if ((bi & (1 << i)) != 0) {
            kind++;
            for (int j = 0; j < m; j++) {
              if (b[i][j] == 1) {
                use[j] = use[j] + 1;
              }
            }
          }
        }
        if (kind > max) {
          bool ok = true;
          for (int j = 0; j < m; j++) {
            if (use[j] % 2 == 1) {
              ok = false;
            }
          }
          if (ok) {
            max = kind;
          }
        }
      }
      cout << max << endl;
    } else { /* mが小さい場合: 各材料が余っているか否かでbit-dp */
      int dp[1 << m], dpn[1 << m];
      for (int bj = 0; bj < (1 << m); bj++) {
        dp[bj] = -1;
      }
      dp[0] = 0;
      for (int i = 0; i < n; i++) {
        int buse = 0;
        for (int j = 0; j < m; j++) {
          buse = buse * 2 + b[i][j];
        }
        for (int bj = 0; bj < (1 << m); bj++) {
          dpn[bj] = dp[bj];
        }
        for (int bj = 0; bj < (1 << m); bj++) {
          if (dp[bj] != -1 && dp[bj] + 1 > dp[bj ^ buse]) {
            dpn[bj ^ buse] = dp[bj] + 1;
          }
        }
        for (int bj = 0; bj < (1 << m); bj++) {
          dp[bj] = dpn[bj];
        }
      }
      cout << dp[0] << endl;
    }
  }
}