#include <bits/stdc++.h>
using namespace std;
template <class T>
string i2s(T x) {
  ostringstream o;
  o << x;
  return o.str();
}
template <class T>
vector<T> split(const string& s) {
  vector<T> v;
  istringstream is(s);
  T t;
  while (is >> t) v.push_back(t);
  return v;
}
vector<string> splitStr(const string& s, const string& d = "",
                        bool keepEmpty = false) {
  if (d.empty()) return split<string>(s);
  vector<string> v;
  string t;
  for (int _n = ((int((s).size()))), i = 0; i < _n; ++i)
    if (d.find(s[i]) != string::npos) {
      if (keepEmpty || !t.empty()) {
        v.push_back(t);
        t = "";
      }
    } else
      t += s[i];
  if (!t.empty()) v.push_back(t);
  return v;
}
int main() {
  std::ios::sync_with_stdio(false);
  int N, M;
  string s;
  cin >> N >> M;
  vector<string> v(N);
  for (int _n = (N), i = 0; i < _n; ++i) {
    cin >> v[i];
  }
  int mini = 1000, maxi = 0, minj = 1000, maxj = 0;
  for (int _n = (N), i = 0; i < _n; ++i)
    for (int _n = (M), j = 0; j < _n; ++j)
      if (v[i][j] == 'X') {
        mini = min(i, mini);
        minj = min(j, minj);
        maxi = max(i, maxi);
        maxj = max(j, maxj);
      }
  bool poss = true;
  for (int i = (mini); i <= (maxi); ++i)
    for (int j = (minj); j <= (maxj); ++j)
      if (v[i][j] != 'X') {
        poss = false;
        break;
      }
  string ans = (poss ? "YES" : "NO");
  cout << ans << "\n";
  return 0;
}
