Problem p03133 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <vector>

using namespace std;

typedef long long lint;

const int mod = 998244353;

int modpow(int x, int y, int m) {
  int ret = 1 % m, x2p = x;
  while (y > 0) {
    if (y % 2)
      ret = (lint)ret * x2p % m;
    y /= 2;
    x2p = (lint)x2p * x2p % m;
  }
  return ret;
}

int inv(int a, int p) { return modpow(a, p - 2, p); }

vector<int> fact, inv_fact;

void prepare_binom(int lim) {
  fact.resize(lim + 1);
  fact[0] = 1;
  for (int i = 1; i <= lim; ++i)
    fact[i] = (lint)i * fact[i - 1] % mod;

  inv_fact.resize(lim + 1);
  inv_fact[lim] = inv(fact[lim], mod);
  for (int i = lim - 1; i >= 0; --i)
    inv_fact[i] = (lint)(i + 1) * inv_fact[i + 1] % mod;
}

int binom(int a, int b) {
  if (!(0 <= b && b <= a))
    return 0;
  return (lint)fact[a] * inv_fact[b] % mod * inv_fact[a - b] % mod;
}

int main() {
  int n, m;
  scanf("%d %d", &n, &m);

  prepare_binom(min(n, m));

  vector<vector<int>> mat(n, vector<int>(m));
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j) {
      scanf("%d", &mat[i][j]);
      mat[i][j] %= 2;
    }

  int rank = 0;
  for (int x = 0; x < m; ++x) {
    int selected = -1;
    for (int y = rank; y < n; ++y)
      if (mat[y][x])
        selected = y;
    if (selected == -1)
      continue;
    swap(mat[selected], mat[rank]);
    for (int y = rank + 1; y < n; ++y) {
      if (!mat[y][x])
        continue;
      for (int x2 = x; x2 < n; ++x2)
        mat[y][x2] ^= mat[rank][x2];
    }
    ++rank;
  }

  int result = 0;
  for (int i = 1; i <= rank; i += 2)
    result = (result + (lint)binom(rank, i) * modpow(3, rank - i, mod) % mod *
                           modpow(2, n + m - 2 * rank, mod)) %
             mod;
  printf("%d\n", result);

  return 0;
}


Fixed submission:
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <vector>

using namespace std;

typedef long long lint;

const int mod = 998244353;

int modpow(int x, int y, int m) {
  int ret = 1 % m, x2p = x;
  while (y > 0) {
    if (y % 2)
      ret = (lint)ret * x2p % m;
    y /= 2;
    x2p = (lint)x2p * x2p % m;
  }
  return ret;
}

int inv(int a, int p) { return modpow(a, p - 2, p); }

vector<int> fact, inv_fact;

void prepare_binom(int lim) {
  fact.resize(lim + 1);
  fact[0] = 1;
  for (int i = 1; i <= lim; ++i)
    fact[i] = (lint)i * fact[i - 1] % mod;

  inv_fact.resize(lim + 1);
  inv_fact[lim] = inv(fact[lim], mod);
  for (int i = lim - 1; i >= 0; --i)
    inv_fact[i] = (lint)(i + 1) * inv_fact[i + 1] % mod;
}

int binom(int a, int b) {
  if (!(0 <= b && b <= a))
    return 0;
  return (lint)fact[a] * inv_fact[b] % mod * inv_fact[a - b] % mod;
}

int main() {
  int n, m;
  scanf("%d %d", &n, &m);

  prepare_binom(min(n, m));

  vector<vector<int>> mat(n, vector<int>(m));
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j) {
      scanf("%d", &mat[i][j]);
      mat[i][j] %= 2;
    }

  int rank = 0;
  for (int x = 0; x < m; ++x) {
    int selected = -1;
    for (int y = rank; y < n; ++y)
      if (mat[y][x])
        selected = y;
    if (selected == -1)
      continue;
    swap(mat[selected], mat[rank]);
    for (int y = rank + 1; y < n; ++y) {
      if (!mat[y][x])
        continue;
      for (int x2 = x; x2 < m; ++x2)
        mat[y][x2] ^= mat[rank][x2];
    }
    ++rank;
  }

  int result = 0;
  for (int i = 1; i <= rank; i += 2)
    result = (result + (lint)binom(rank, i) * modpow(3, rank - i, mod) % mod *
                           modpow(2, n + m - 2 * rank, mod)) %
             mod;
  printf("%d\n", result);

  return 0;
}