#include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif

//#define int long long
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)
const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9) + 7;
template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int H, W; cin >> H >> W;
	vector<vector<char>> S(H, vector<char>(W));
	rep(i, 0, H) rep(j, 0, W) { cin >> S[i][j]; }

	vector<vector<int>> alphaH(H, vector<int>(26));
	vector<vector<int>> alphaW(W, vector<int>(26));

	rep(i, 0, H) {
		rep(j, 0, W) {
			alphaH[i][S[i][j] - 'a']++;
		}
	}
	rep(j, 0, W) {
		rep(i, 0, H) {
			alphaW[j][S[i][j] - 'a']++;
		}
	}
	dump(alphaH);
	dump(alphaW);

	int s;
	bool yes = true;

	vector<bool> usedH(H);
	rep(i, 0, H) {
		if (usedH[i])continue;
		rep(ni, i + 1, H) {
			if (usedH[ni])continue;
			bool same = true;
			rep(c, 0, 26) {
				if (alphaH[i][c] != alphaH[ni][c])
					same = false;
			}
			if (same) {
				usedH[i] = usedH[ni] = true;
			}
		}
	}

	dump(count(all(usedH), false));
	if (H % 2 < count(all(usedH), false)) {
		yes = false;
	}

	vector<bool> usedW(W);
	rep(j, 0, W) {
		if (usedW[j])continue;
		rep(nj, j + 1, W) {
			if (usedW[nj])continue;
			bool same = true;
			rep(c, 0, 26) {
				if (alphaW[j][c] != alphaW[nj][c])
					same = false;
			}
			if (same) {
				usedW[j] = usedW[nj] = true;
			}
		}
	}

	dump(count(all(usedW), false));
	if (W % 2 < count(all(usedW), false)) {
		yes = false;
	}

	vector<bool> pairusedH(H);
	rep(i, 0, H) {
		if (!usedH[i])continue;
		rep(ni, i + 1, H) {
			if (!usedH[ni])continue;
			bool same = true;
			rep(c, 0, 26) {
				if (alphaH[i][c] != alphaH[ni][c])
					same = false;
			}
			if (!same)continue;
			vector<bool> pairused(W);
			rep(j, 0, W) {
				if (pairused[j])continue;
				char a = S[i][j];
				char b = S[ni][j];
				rep(nj, j + 1, W) {
					if (pairused[nj])continue;
					if (S[i][nj] == b&&S[ni][nj] == a) {
						pairused[j] = true;
						pairused[nj] = true;
						break;
					}
				}
			}
			if (W % 2 == count(all(pairused), false)) {
				pairusedH[i] = pairusedH[ni] = true;
				break;
			}
		}
	}
	dump(count(all(pairusedH), false) - count(all(usedH), false));
	if (count(all(pairusedH), false) - count(all(usedH), false)) {
		yes = false;
	}
	vector<bool> pairusedW(W);
	rep(j, 0, W) {
		if (!usedW[j])continue;
		rep(nj, j + 1, W) {
			if (!usedW[nj])continue;
			bool same = true;
			rep(c, 0, 26) {
				if (alphaW[j][c] != alphaW[nj][c])
					same = false;
			}
			if (!same)continue;
			vector<bool> pairused(H);
			rep(i, 0, H) {
				if (pairused[i])continue;
				char a = S[i][j];
				char b = S[i][nj];
				rep(ni, i + 1, H) {
					if (pairused[ni])continue;
					if (S[ni][j] == b&&S[ni][nj] == a) {
						pairused[i] = true;
						pairused[ni] = true;
						break;
					}
				}
			}
			if (H % 2 == count(all(pairused), false)) {
				pairusedW[j] = pairusedW[nj] = true;
				break;
			}
		}
	}
	dump(count(all(pairusedW), false) - count(all(usedW), false));
	if (count(all(pairusedW), false) - count(all(usedW), false)) {
		yes = false;
	}

	if (yes) {
		cout << "YES" << endl;
	}
	else {
		cout << "NO" << endl;
	}


	return 0;
}

Measured memory_bytes: 256