Language: C++

#include <bits/stdc++.h>
using namespace std;

#define fs first
#define sc second
#define pb emplace_back
#define mp make_pair
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()

const int32_t inf = 1001001001;
const int64_t infll = 1001001001001001001ll;
const int dx[] = {0, -1, 1, 0, -1, 1, -1, 1}, dy[] = {-1, 0, 0, 1, -1, -1, 1, 1};

template <typename T> using vector2d = vector<vector<T>>;

// clang-format off
template <typename T> void sort(vector<T> &v) { sort(all(v)); }
// ostream &operator<<(ostream &os, __int128_t value) { if (ostream::sentry(os)) { __uint128_t tmp = value < 0 ? -value : value; char buffer[64]; char *d = end(buffer); do { --d; *d = "0123456789"[tmp % 10]; tmp /= 10; } while (tmp != 0); if (value < 0) { --d; *d = '-'; } int len = end(buffer) - d; if (os.rdbuf()->sputn(d, len) != len) { os.setstate(ios_base::badbit); }} return os; }
// istream &operator>>(istream &is, __int128_t &value) { string in; is >> in; value = 0; for (const char &c : in) { if ('0' <= c && c <= '9') value = 10 * value + (c - '0'); } if (in[0] == '-') value *= -1; return is; }
// ostream &operator<<(ostream &os, __uint128_t value) { if (ostream::sentry(os)) { char buffer[64]; char *d = end(buffer); do { --d; *d = "0123456789"[value % 10]; value /= 10; } while (value != 0); int len = end(buffer) - d; if (os.rdbuf()->sputn(d, len) != len) { os.setstate(ios_base::badbit); }} return os; }
// istream &operator>>(istream &is, __uint128_t &value) { string in; is >> in; value = 0; for (const char &c : in) { if ('0' <= c && c <= '9') value = 10 * value + (c - '0'); } return is; }
template <typename T> ostream &operator<<(ostream &os, vector<T> &v) { os << v[0]; for (int i = 1; i < v.size(); ++i) os << " " << v[i]; return os; }
template <typename T> istream &operator>>(istream &is, vector<T> &v) { for (T &in : v) is >> in; return is; }
template <typename T1, typename T2> ostream &operator<<(ostream &os, pair<T1, T2> p) { os << p.fs << " " << p.sc; return os; }
template <typename T1, typename T2> istream &operator>>(istream &is, pair<T1, T2> &p) { is >> p.fs >> p.sc; return is; }

struct IoSetup { IoSetup(){ cin.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(10); cerr << fixed << setprecision(10); } } iosetup;

inline int64_t in() { int64_t x = 0; cin >> x; return x; }
template <typename T1, typename T2> inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }
template <typename T1, typename T2> inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }
// clang-format on

// int h, w;
// vector<vector<char>> a;
//
// bool check(vector<char> s, vector<char> t) {
//   int n = s.size();
//   for (int i = 0; i < s.size(); ++i) {
//     if (s[i] == '-') continue;
//     for (int j = i + 1; j < t.size(); ++j) {
//       if (t[j] == '-') continue;
//       if (s[i] == t[j] && s[j] == t[i]) {
//         s[i] = t[i] = s[j] = t[i] = '-';
//         n -= 2;
//       }
//     }
//   }
//
//   return (s.size() & 1 ? n == 1 : n == 0);
// }
//
// bool search(int bit) {
//
// }
//
// // bool dfs(int bit) {
// //   if (bit == (1 << h) - 1) return true;
// //
// //   for (int i = 0; i < h; ++i) {
// //     if (bit & (1 << i)) continue;
// //     for (int j = i + 1; j < h; ++j) {
// //       if (bit & (1 << j)) continue;
// //
// //       if (check(a[i], a[j])) {
// //         if (dfs(bit | (1 << i) | (1 << j))) return true;
// //       }
// //     }
// //   }
// //
// //   return false;
// // }
//
// signed main(int argc, char *argv[]) {
//   cin >> h >> w;
//   a.assign(h, vector<char>(w));
//   for (int i = 0; i < h; ++i) {
//     for (int j = 0; j < w; ++j) {
//       cin >> a[i][j];
//     }
//   }
//
//   if (w & 1) {
//     int cnt[256] = {};
//     for (int j = 0; j < w; ++j) {
//       bool f = true;
//       for (int i = 1; i < h; ++i) {
//         if (a[i - 1][j] != a[i][j]) f = false;
//       }
//
//       if (f) {
//         cnt[a[0][j]]++;
//       }
//     }
//
//     vector<char> v;
//     for (char c = 'a'; c <= 'z'; ++c) {
//       if (cnt[c] & 1) v.push_back(c);
//     }
//
//     if (v.size() != 1) {
//       cout << "NO" << endl;
//       return 0;
//     }
//
//     for (int j = 0; j < w; ++j) {
//       if (a[0][j] != v[0]) continue;
//       bool f = true;
//       for (int i = 0; i < h; ++i) {
//         if (a[i][j] != v[0]) f = false;
//       }
//
//       if (f) {
//         for (int i = 0; i < h; ++i) {
//           a[i][j] = '-';
//         }
//         break;
//       }
//     }
//
//     for (int i = 0; i < h; ++i) {
//       for (int j = 0; j + 1 < w; ++j) {
//         if (a[i][j] == '-') swap(a[i][j], a[i][j + 1]);
//       }
//
//       a[i].pop_back();
//     }
//
//     w--;
//   }
//
//   if (h & 1) {
//     for (int i = 0; i < h; ++i) {
//       bool f = true;
//       for (int j = 1; j < w; ++j) {
//         if (a[i][j] != a[i][j - 1]) f = false;
//       }
//
//       if (f) {
//         if (dfs(1 << i)) {
//           cout << "YES" << endl;
//           return 0;
//         }
//       }
//     }
//
//     cout << "NO" << endl;
//   } else {
//     if (dfs(0)) {
//       cout << "YES" << endl;
//     } else {
//       cout << "NO" << endl;
//     }
//   }
//
//   // cout << boolalpha << check(a[0], a[1]) << endl;
// }

int h, w;
vector<string> a;
vector<pair<int, int>> v;

bool check(int bit, string &s, string &t) {
  if (bit == (1 << h) - 1) return true;

  for (int i = 0; i < h; ++i) {
    if (bit & (1 << i)) continue;
    for (int j = i + 1; j < h; ++j) {
      if (bit & (1 << j)) continue;

      bool f = true;
      for (int k = 0; k < v.size(); ++k) {
        int a = v[k].fs;
        int b = v[k].sc;
        if (s[a] != t[b] || s[b] != t[a]) f = false;
      }

      if (f) {
        if (check(bit | (1 << i) | (1 << j), s, t)) return true;
      }
    }
  }

  return false;
}

bool dfs(string s, string t) {
  if (v.size() == w / 2) {
    if (check(0, s, t)) return true;
  }
  for (int i = 0; i < s.size(); ++i) {
    if (s[i] == '-') continue;
    for (int j = 0; j < t.size(); ++j) {
      if (t[j] == '-') continue;

      if (s[i] == t[j] && t[i] == s[j]) {
        s[i] = t[i] = s[j] = t[j] = '-';
        v.push_back(make_pair(i, j));
        if (dfs(s, t)) return true;
        v.pop_back();
      }
    }
  }
}

int main() {
  cin >> h >> w;

  a.assign(h);
  for (auto &i : a) cin >> i;

  if (w & 1) {
    int cnt[256] = {};
    for (int j = 0; j < w; ++j) {
      bool f = true;
      for (int i = 1; i < h; ++i) {
        if (a[i - 1][j] != a[i][j]) f = false;
      }

      if (f) {
        cnt[a[0][j]]++;
      }
    }

    vector<char> v;
    for (char c = 'a'; c <= 'z'; ++c) {
      if (cnt[c] & 1) v.push_back(c);
    }

    if (v.size() != 1) {
      cout << "NO" << endl;
      return 0;
    }

    for (int j = 0; j < w; ++j) {
      if (a[0][j] != v[0]) continue;
      bool f = true;
      for (int i = 0; i < h; ++i) {
        if (a[i][j] != v[0]) f = false;
      }

      if (f) {
        for (int i = 0; i < h; ++i) {
          a[i][j] = '-';
        }
        break;
      }
    }

    for (int i = 0; i < h; ++i) {
      for (int j = 0; j + 1 < w; ++j) {
        if (a[i][j] == '-') swap(a[i][j], a[i][j + 1]);
      }

      a[i].pop_back();
    }

    w--;
  }

  if (h & 1) {
    int cnt[256] = {};
    for (int i = 0; i < h; ++i) {
      bool f = true;
      for (int j = 1; j < w; ++j) {
        if (a[i][j - 1] != a[i][j]) f = false;
      }

      if (f) cnt[a[i][0]]++;
    }

    vector<char> v;
    for (char c = 'a'; c <= 'z'; ++c) {
      if (cnt[c] & 1) v.push_back(c);
    }

    if (v.size() != 1) {
      cout << "NO" << endl;
      return 0;
    }

    for (int i = 0; i < h; ++i) {
      bool f = true;
      for (int j = 0; j < w; ++j) {
        if (a[i][j] != v[0]) f = false;
      }

      if (f) {
        for (int j = 0; j < w; ++j) {
          a[i][j] = '-';
        }
        break;
      }
    }

    for (int j = 0; j < w; ++j) {
      for (int i = 0; i + 1 < h; ++i) {
        if (a[i][j] == '-') swap(a[i][j], a[i + 1][j]);
      }
    }
    a.pop_back();

    h--;
  }

  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      cerr << a[i][j];
    }
    cerr << endl;
  }

  for (int i = 1; i < h; ++i) {
    if (dfs(a[i], a[0])) {
      cout << "YES" << endl;
      return 0;
    }
  }

  cout << "NO" << endl;
}


Compiler output:
a.cc: In function 'int main()':
a.cc:210:11: error: no matching function for call to 'std::vector<std::__cxx11::basic_string<char> >::assign(int&)'
  210 |   a.assign(h);
      |   ~~~~~~~~^~~
In file included from /usr/include/c++/14/vector:66,
                 from /usr/include/c++/14/functional:64,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:53,
                 from a.cc:1:
/usr/include/c++/14/bits/stl_vector.h:828:9: note: candidate: 'template<class _InputIterator, class> void std::vector<_Tp, _Alloc>::assign(_InputIterator, _InputIterator) [with <template-parameter-2-2> = _InputIterator; _Tp = std::__cxx11::basic_string<char>; _Alloc = std::allocator<std::__cxx11::basic_string<char> >]'
  828 |         assign(_InputIterator __first, _InputIterator __last)
      |         ^~~~~~
/usr/include/c++/14/bits/stl_vector.h:828:9: note:   candidate expects 2 arguments, 1 provided
/usr/include/c++/14/bits/stl_vector.h:808:7: note: candidate: 'void std::vector<_Tp, _Alloc>::assign(size_type, const value_type&) [with _Tp = std::__cxx11::basic_string<char>; _Alloc = std::allocator<std::__cxx11::basic_string<char> >; size_type = long unsigned int; value_type = std::__cxx11::basic_string<char>]'
  808 |       assign(size_type __n, const value_type& __val)
      |       ^~~~~~
/usr/include/c++/14/bits/stl_vector.h:808:7: note:   candidate expects 2 arguments, 1 provided
/usr/include/c++/14/bits/stl_vector.h:855:7: note: candidate: 'void std::vector<_Tp, _Alloc>::assign(std::initializer_list<_Tp>) [with _Tp = std::__cxx11::basic_string<char>; _Alloc = std::allocator<std::__cxx11::basic_string<char> >]'
  855 |       assign(initializer_list<value_type> __l)
      |       ^~~~~~
/usr/include/c++/14/bits/stl_vector.h:855:43: note:   no known conversion for argument 1 from 'int' to 'std::initializer_list<std::__cxx11::basic_string<char> >'
  855 |       assign(initializer_list<value_type> __l)
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
a.cc: In function 'bool dfs(std::string, std::string)':
a.cc:205:1: warning: control reaches end of non-void function [-Wreturn-type]
  205 | }
      | ^