#include <bits/stdc++.h>
using namespace std;
template <class T>
inline T checkmin(T &a, T b) {
  return (a < b) ? a : a = b;
}
template <class T>
inline T checkmax(T &a, T b) {
  return (a > b) ? a : a = b;
}
template <class T>
T GCD(T a, T b) {
  if (a < 0) return GCD(-a, b);
  if (b < 0) return GCD(a, -b);
  return (a == 0) ? b : GCD(b % a, a);
}
template <class T>
T LCM(T a, T b) {
  if (a < 0) return LCM(-a, b);
  if (b < 0) return LCM(a, -b);
  return (a == 0 || b == 0) ? 0 : a / GCD(a, b) * b;
}
template <class T>
inline T sqr(T X) {
  return X * X;
}
namespace Poor {
int N, K;
bool Able[4];
bool IsVowel(char Ch) {
  return Ch == 'a' || Ch == 'e' || Ch == 'i' || Ch == 'o' || Ch == 'u';
}
bool Cut(string &S) {
  int Cnt = 0;
  for (int i = (int)S.size() - 1; i >= 0; --i)
    if (IsVowel(S[i])) {
      ++Cnt;
      if (Cnt == K) {
        S = S.substr(i);
        return 1;
      }
    }
  return 0;
}
void Process() {
  string A, B, C, D;
  cin >> A >> B >> C >> D;
  if (!Cut(A) || !Cut(B) || !Cut(C) || !Cut(D)) fill(Able, Able + 4, 0);
  Able[0] &= (A == B && B == C && C == D);
  Able[1] &= (A == B && C == D);
  Able[2] &= (A == C && B == D);
  Able[3] &= (A == D && B == C);
}
void Run() {
  fill(Able, Able + 4, 1);
  cin >> N >> K;
  for (int i = 1; i <= N; ++i) Process();
  if (Able[0]) {
    puts("aaaa");
    return;
  }
  if (Able[1]) {
    puts("aabb");
    return;
  }
  if (Able[2]) {
    puts("abab");
    return;
  }
  if (Able[3]) {
    puts("abba");
    return;
  }
  puts("NO");
}
}  // namespace Poor
int main() {
  Poor::Run();
  return 0;
}
