Problem p03383 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
using Int = long long;
int PREP = (cin.tie(nullptr), ios::sync_with_stdio(false),
            cout << fixed << setprecision(9), 0);
int SEGV =
    getenv("D") ||
    (exit(system("D= SEGFAULT_SIGNALS=all catchsegv ./prog.exe") >> 8), 0);
void check(const vector<string> &A) {
  int H = A.size(), W = A[0].size();
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (A[i][j] != A[H - 1 - i][W - 1 - j]) {
        return;
      }
    }
  }
  cout << "YES\n";
  exit(0);
}
bool revequal(const string &s, const string &t) {
  if (s.size() != t.size())
    return false;
  for (int i = 0; i < s.size(); i++) {
    if (s[i] != t[s.size() - 1 - i])
      return false;
  }
  return true;
}
int main() {
  int H, W;
  cin >> H >> W;
  vector<string> A(H);
  for (auto &a : A)
    cin >> a;
  map<string, vector<int>> M;
  for (int i = 0; i < H; i++) {
    string s = A[i];
    sort(begin(s), end(s));
    M[s].push_back(i);
  }
  vector<pair<string, vector<int>>> rows(begin(M), end(M));
  vector<string> B(H);
  auto column = [&]() {
    vector<string> C(W), D(W);
    for (int i = 0; i < W; i++) {
      string s;
      for (int j = 0; j < H; j++)
        s.push_back(B[j][i]);
      C[i] = s;
    }
    vector<int> done(W);
    int cnt = 0;
    for (int i = 0; i < W; i++) {
      for (int j = i + 1; j < W; j++) {
        if (done[i] || done[j])
          continue;
        if (revequal(C[i], C[j])) {
          D[cnt] = C[i];
          D[W - 1 - cnt] = C[j];
          cnt++;
          done[i] = done[j] = 1;
        }
      }
    }
    for (int i = 0; i < W; i++) {
      if (!done[i]) {
        D[cnt] = C[i];
        done[i] = 1;
        break;
      }
    }
    if (accumulate(begin(done), end(done), 0) == W) {
      check(D);
    }
  };
  auto recur = [&](auto &recur, int idx, int t, int center) -> void {
    if (idx >= rows.size()) {
      column();
      return;
    }
    auto &p = rows[idx];
    int flag = p.second.size() % 2;
    if (flag && center)
      return;
    center = flag;
    vector<bool> used(p.second.size());
    auto recur2 = [&](auto &recur2) -> void {
      int i = 0;
      while (i < p.second.size() && used[i])
        i++;
      if (i == p.second.size()) {
        recur(recur, idx + 1, t, center);
        return;
      }
      used[i] = 1, B[t] = A[p.second[i]];
      for (int j = i + 1; j < p.second.size(); j++)
        if (!used[j]) {
          used[j] = 1, B[H - 1 - t] = A[p.second[j]];
          t++;
          recur2(recur2);
          t--;
          used[j] = 0;
        }
      used[i] = 0;
    };
    for (int i = 0; i < (flag ? p.second.size() : 1); i++) {
      if (flag)
        used[i] = 1, B[H / 2] = A[p.second[i]];
      recur2(recur2);
    }
  };
  recur(recur, 0, 0, 0);
  cout << "NO\n";
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using Int = long long;
int PREP = (cin.tie(nullptr), ios::sync_with_stdio(false),
            cout << fixed << setprecision(9), 0);
// int SEGV = getenv("D") || (exit(system("D= SEGFAULT_SIGNALS=all catchsegv
// ./prog.exe") >> 8), 0);
void check(const vector<string> &A) {
  int H = A.size(), W = A[0].size();
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (A[i][j] != A[H - 1 - i][W - 1 - j]) {
        return;
      }
    }
  }
  cout << "YES\n";
  exit(0);
}
bool revequal(const string &s, const string &t) {
  if (s.size() != t.size())
    return false;
  for (int i = 0; i < s.size(); i++) {
    if (s[i] != t[s.size() - 1 - i])
      return false;
  }
  return true;
}
int main() {
  int H, W;
  cin >> H >> W;
  vector<string> A(H);
  for (auto &a : A)
    cin >> a;
  map<string, vector<int>> M;
  for (int i = 0; i < H; i++) {
    string s = A[i];
    sort(begin(s), end(s));
    M[s].push_back(i);
  }
  vector<pair<string, vector<int>>> rows(begin(M), end(M));
  vector<string> B(H);
  auto column = [&]() {
    vector<string> C(W), D(W);
    for (int i = 0; i < W; i++) {
      string s;
      for (int j = 0; j < H; j++)
        s.push_back(B[j][i]);
      C[i] = s;
    }
    vector<int> done(W);
    int cnt = 0;
    for (int i = 0; i < W; i++) {
      for (int j = i + 1; j < W; j++) {
        if (done[i] || done[j])
          continue;
        if (revequal(C[i], C[j])) {
          D[cnt] = C[i];
          D[W - 1 - cnt] = C[j];
          cnt++;
          done[i] = done[j] = 1;
        }
      }
    }
    for (int i = 0; i < W; i++) {
      if (!done[i]) {
        D[cnt] = C[i];
        done[i] = 1;
        break;
      }
    }
    if (accumulate(begin(done), end(done), 0) == W) {
      check(D);
    }
  };
  auto recur = [&](auto &recur, int idx, int t, int center) -> void {
    if (idx >= rows.size()) {
      column();
      return;
    }
    auto &p = rows[idx];
    int flag = p.second.size() % 2;
    if (flag && center)
      return;
    center = flag;
    vector<bool> used(p.second.size());
    auto recur2 = [&](auto &recur2) -> void {
      int i = 0;
      while (i < p.second.size() && used[i])
        i++;
      if (i == p.second.size()) {
        recur(recur, idx + 1, t, center);
        return;
      }
      used[i] = 1, B[t] = A[p.second[i]];
      for (int j = i + 1; j < p.second.size(); j++)
        if (!used[j]) {
          used[j] = 1, B[H - 1 - t] = A[p.second[j]];
          t++;
          recur2(recur2);
          t--;
          used[j] = 0;
        }
      used[i] = 0;
    };
    for (int i = 0; i < (flag ? p.second.size() : 1); i++) {
      if (flag)
        used[i] = 1, B[H / 2] = A[p.second[i]];
      recur2(recur2);
    }
  };
  recur(recur, 0, 0, 0);
  cout << "NO\n";
  return 0;
}