Problem:
Problem Statement
We found a dictionary of the Ancient Civilization Mayo (ACM) during excavation of the ruins.
After analysis of the dictionary, we revealed they used a language that had not more than 26 letters.
So one of us mapped each letter to a different English alphabet and typed all the words in the dictionary into a computer.
How the words are ordered in the dictionary, especially whether they are ordered lexicographically, is an interesting topic to many people.
As a good programmer, you are requested to write a program to judge whether we can consider the words to be sorted in a lexicographical order.
Note:
In a lexicographical order, a word always precedes other words it is a prefix of.
For example,
ab
precedes
abc
,
abde
, and so on.
Input
The input consists of multiple datasets. Each dataset is formatted as follows:
n
string_1
...
string_n
Each dataset consists of
n+1
lines.
The first line of each dataset contains an integer that indicates
n
(
1 \leq n \leq 500
).
The
i
-th line of the following
n
lines contains
string_i
, which consists of up to 10 English lowercase letters.
The end of the input is
0
, and this should not be processed.
Output
Print either
yes
or
no
in a line for each dataset, in the order of the input.
If all words in the dataset can be considered to be ordered lexicographically, print
yes
.
Otherwise, print
no
.
Sample Input
4
cba
cab
b
a
3
bca
ab
a
5
abc
acb
b
c
c
5
abc
acb
c
b
b
0
Output for the Sample Input
yes
no
yes
no

Submitted solutions:

code_snippet: #include <iostream>
#include <iomanip>
#include <cassert>
#include <vector>
#include <algorithm>
#include <utility>
#include <numeric>
#include <tuple>
#include <ranges>
namespace ranges = std::ranges;
namespace views = std::views;
// #include "Src/Number/IntegerDivision.hpp"
// #include "Src/Utility/BinarySearch.hpp"
// #include "Src/Sequence/CompressedSequence.hpp"
// #include "Src/Sequence/RunLengthEncoding.hpp"
// #include "Src/Algebra/Group/AdditiveGroup.hpp"
// #include "Src/DataStructure/FenwickTree/FenwickTree.hpp"
// #include "Src/DataStructure/SegmentTree/SegmentTree.hpp"
// using namespace zawa;
// #include "atcoder/modint"
// using mint = atcoder::modint998244353;
int N;
std::string S[500];
bool solve() {
    std::cin >> N;
    if (N == 0) return false;
    for (int i = 0 ; i < N ; i++) std::cin >> S[i];
    std::vector<std::vector<int>> g(26);
    for (int i = 0 ; i < N ; i++) {
        for (int j = i + 1 ; j < N ; j++) {
            const int m = std::min(std::ssize(S[i]), std::ssize(S[j]));
            bool fn = false;
            for (int k = 0 ; !fn and k < m ; k++) if (S[i][k] != S[j][k])  {
                // std::cout << S[i][k] << " -> " << S[j][k] << std::endl;
                g[S[i][k] - 'a'].push_back(S[j][k] - 'a');
                fn = true;
            }
            if (!fn and S[i].size() > S[j].size()) {
                std::cout << "no\n";
                return true;
            }
        }
    }
    for (int i = 0 ; i < 26 ; i++) {
        ranges::sort(g[i]);
        g[i].erase(std::unique(g[i].begin(), g[i].end()), g[i].end());
    }
    std::vector<int> deg(26);
    for (int i = 0 ; i < 26 ; i++) {
        for (int x : g[i]) deg[x]++;
    }
    std::vector<int> que;
    for (int i = 0 ; i < 26 ; i++) if (deg[i] == 0) que.push_back(i);
    for (int t = 0 ; t < 26 ; t++) {
        if (t >= std::ssize(que)) {
            std::cout << "no\n";
            return true;
        }
        const int v = que[t];
        for (int x : g[v]) {
            deg[x]--;
            if (deg[x] == 0) que.push_back(x);
        }
    }
    std::cout << "yes\n";
    return true;
}
int main() {
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    std::ios::sync_with_stdio(false);
    while (solve()) ;
}
accuracy: 1
time_ms: 20
memory_kb: 4360
final_rank: 13

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

string solve(int n) {
    vector<string> s = in(n);
    vector data(26, vector(26, -1));
    for(int i : rep(n)) for(int j : rep(i + 1, n)) {
        string& t = s[i];
        string& u = s[j];
        if(t == u) continue;
        const int tsz = t.size();
        const int usz = u.size();
        int ti = 0, ui = 0;
        while(ti < tsz and ui < usz and t[ti] == u[ui]) ti++, ui++;
        if(ti < tsz and ui < usz) {
            int tn = t[ti] - 'a', un = u[ui] - 'a';
            if(data[tn][un] == -1) {
                data[tn][un] = 1;
                data[un][tn] = 0;
            } else if(data[tn][un] == 0) {
                return "no";
            }
        } else if(ti < tsz and ui == usz) {
            return "no";
        }
    }

    return "yes";
}

int main() {
    while(true) {
        int n = in();
        if(n == 0) return 0;
        print(solve(n));
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3420
final_rank: 5

code_snippet: #pragma region template
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#ifdef __LOCAL
 #include <debug>
#else
 #define debug(...) void(0)
#endif

using ll=long long;
using ld=long double;
using vi=vector<int>;
using vll=vector<ll>;
using pi=pair<int,int>;
using pll=pair<ll,ll>;

#define overload2(a,b,c,...) c
#define overload3(a,b,c,d,...) d
#define overload4(a,b,c,d,e,...) e
#define overload5(a,b,c,d,e,f,...) f

#define TYPE1(T) template<typename T>
#define TYPE2(T,U) template<typename T,typename U>
#define TYPE(...) overload2(__VA_ARGS__,TYPE2,TYPE1)(__VA_ARGS__)
#define TYPES1(T) template<typename... T>
#define TYPES2(H,T) template<typename H,typename... T>
#define TYPES(...) overload2(__VA_ARGS__,TYPES2,TYPES1)(__VA_ARGS__)

#define REP4(i,s,n,d) for(ll i=(s);i<(n);i+=(d))
#define REP3(i,s,n) REP4(i,s,n,1)
#define REP2(i,n) REP3(i,0,n)
#define REP1(n) REP2(tomato,n)
#define REP(...) overload4(__VA_ARGS__,REP4,REP3,REP2,REP1)(__VA_ARGS__)

#define RREP4(i,s,n,d) for(ll i=(n)-1;i>=s;i-=d)
#define RREP3(i,s,n) RREP4(i,s,n,1)
#define RREP2(i,n) RREP3(i,0,n)
#define RREP1(n) RREP2(tomato,n)
#define RREP(...) overload4(__VA_ARGS__,RREP4,RREP3,RREP2,RREP1)(__VA_ARGS__)

#define ALL(v) v.begin(),v.end()
#define RALL(v) v.rbegin(),v.rend()
#define SORT(v) sort(ALL(v))
#define RSORT(v) sort(RALL(v))
#define REVERSE(v) reverse(ALL(v))
#define UNIQUE(v) SORT(v),v.erase(unique(ALL(v)),v.end())

TYPES(T) void input(T&... a){ (cin>>...>>a); }
#define DECLARE(T,...) T __VA_ARGS__;input(__VA_ARGS__);
#define INT(...) DECLARE(int,__VA_ARGS__)
#define STR(...) DECLARE(string,__VA_ARGS__)
#define LL(...) DECLARE(long long,__VA_ARGS__)
#define CHR(...) DECLARE(char,__VA_ARGS__)
#define DBL(...) DECLARE(double,__VA_ARGS__)

TYPE(T)
istream&operator>>(istream&is,vector<T>&v){
  for(auto&a:v)cin>>a;
  return is;
}
TYPE(T)
ostream&operator<<(ostream&os,vector<T>&v){
  if(&os==&cerr)os<<"[";
  REP(i,v.size()){
    os<<v[i];
    if(i+1<v.size())os<<(&os==&cerr?",":" ");
  }
  if(&os==&cerr)os<<"]";
  return os;
}

#pragma endregion template

string solve(int n){
  vector<string> s(n);
  cin>>s;
  vector<vector<int>> g(26);
  REP(i,n)REP(j,i){
    if(s[i]==s[j])continue;
    int id=0;
    while(id<s[i].size() and id<s[j].size() and s[i][id]==s[j][id])id++;
    if(id==s[i].size())return "no";
    if(id==s[j].size())continue;
    g[s[j][id]-'a'].push_back(s[i][id]-'a');
  }

  debug(g);

  vector<int> in(26,0);
  queue<int> que;
  REP(i,26)for(int p:g[i])in[p]++;
  REP(i,26)if(!in[i])que.push(i);
  while(que.size()){
    int p=que.front();que.pop();
    for(int q:g[p]){
      if(!--in[q])que.push(q);
    }
  }
  REP(i,26)if(in[i])return "no";
  return "yes";
}

int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int n;
  while(cin>>n,n){
    cout<<solve(n)<<"\n";
  }
}
accuracy: 1
time_ms: 10
memory_kb: 4300
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#include <chrono>
#include <thread>
////#include <atcoder/all>

//using namespace atcoder;
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vvvb = vector<vvb>;
using vd = vector<double>;
using vvd = vector<vd>;
using vvvd = vector<vvd>;
#define all(A) A.begin(),A.end()
#define ALL(A) A.begin(),A.end()
#define rep(i, n) for (ll i = 0; i < (ll) (n); i++)
using pqr = priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>>;

template<class T>
bool chmax(T& p, T q, bool C = 1) {
    if (C == 0 && p == q) {
        return 1;
    }
    if (p < q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}

double EPS = 1e-9;
template<class T>
bool chmin(T& p, T q) {
    if (p > q + EPS) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}

ll gcd(ll(a), ll(b)) {
    if (b == 0)return a;
    ll c = a;
    while (a % b != 0) {
        c = a % b;
        a = b;
        b = c;
    }
    return b;
}

vector<ll> fact, factinv, inv;
ll mod = 998244353;
void prenCkModp(ll n) {
    fact.resize(n + 5);
    factinv.resize(n + 5);
    inv.resize(n + 5);
    fact.at(0) = fact.at(1) = 1;
    factinv.at(0) = factinv.at(1) = 1;
    inv.at(1) = 1;
    for (ll i = 2; i < n + 5; i++) {
        fact.at(i) = (fact.at(i - 1) * i) % mod;
        inv.at(i) = mod - (inv.at(mod % i) * (mod / i)) % mod;
        factinv.at(i) = (factinv.at(i - 1) * inv.at(i)) % mod;
    }

}
ll nCk(ll n, ll k) {
    if (k < 0)return 0;
    if (n < k) return 0;
    return fact.at(n) * (factinv.at(k) * factinv.at(n - k) % mod) % mod;
}







namespace atcoder {
namespace internal {

template <class E> struct csr {
    std::vector<int> start;
    std::vector<E> elist;
    csr(int n, const std::vector<std::pair<int, E>>& edges)
        : start(n + 1), elist(edges.size()) {
        for (auto e : edges) {
            start[e.first + 1]++;
        }
        for (int i = 1; i <= n; i++) {
            start[i] += start[i - 1];
        }
        auto counter = start;
        for (auto e : edges) {
            elist[counter[e.first]++] = e.second;
        }
    }
};

// Reference:
// R. Tarjan,
// Depth-First Search and Linear Graph Algorithms
struct scc_graph {
  public:
    scc_graph(int n) : _n(n) {}

    int num_vertices() { return _n; }

    void add_edge(int from, int to) { edges.push_back({from, {to}}); }

    // @return pair of (# of scc, scc id)
    std::pair<int, std::vector<int>> scc_ids() {
        auto g = csr<edge>(_n, edges);
        int now_ord = 0, group_num = 0;
        std::vector<int> visited, low(_n), ord(_n, -1), ids(_n);
        visited.reserve(_n);
        auto dfs = [&](auto self, int v) -> void {
            low[v] = ord[v] = now_ord++;
            visited.push_back(v);
            for (int i = g.start[v]; i < g.start[v + 1]; i++) {
                auto to = g.elist[i].to;
                if (ord[to] == -1) {
                    self(self, to);
                    low[v] = std::min(low[v], low[to]);
                } else {
                    low[v] = std::min(low[v], ord[to]);
                }
            }
            if (low[v] == ord[v]) {
                while (true) {
                    int u = visited.back();
                    visited.pop_back();
                    ord[u] = _n;
                    ids[u] = group_num;
                    if (u == v) break;
                }
                group_num++;
            }
        };
        for (int i = 0; i < _n; i++) {
            if (ord[i] == -1) dfs(dfs, i);
        }
        for (auto& x : ids) {
            x = group_num - 1 - x;
        }
        return {group_num, ids};
    }

    std::vector<std::vector<int>> scc() {
        auto ids = scc_ids();
        int group_num = ids.first;
        std::vector<int> counts(group_num);
        for (auto x : ids.second) counts[x]++;
        std::vector<std::vector<int>> groups(ids.first);
        for (int i = 0; i < group_num; i++) {
            groups[i].reserve(counts[i]);
        }
        for (int i = 0; i < _n; i++) {
            groups[ids.second[i]].push_back(i);
        }
        return groups;
    }

  private:
    int _n;
    struct edge {
        int to;
    };
    std::vector<std::pair<int, edge>> edges;
};

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

struct scc_graph {
  public:
    scc_graph() : internal(0) {}
    scc_graph(int n) : internal(n) {}

    void add_edge(int from, int to) {
        int n = internal.num_vertices();
        //assert(0 <= from && from < n);
        //assert(0 <= to && to < n);
        internal.add_edge(from, to);
    }

    std::vector<std::vector<int>> scc() { return internal.scc(); }

  private:
    internal::scc_graph internal;
};

}  // 
using namespace atcoder;




int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    while(1){
        ll N;
        cin>>N;
        if(N==0)return 0;
        vector<string> S(N); 
        rep(i,N)cin>>S[i];
        scc_graph D(26);
        bool OK=1;
        rep(i,N){
            rep(j,i){
                ll k=0;
                while(1){
                    if(S[i][k]!=S[j][k]){
                        D.add_edge(S[j][k]-'a',S[i][k]-'a');
                        break;
                    }
                    k++;
                    if(k==S[i].size()){
                        //OK=0;
                        if(k!=S[j].size()){
                            OK=0;
                            break;
                        }
                        else break;
                    }
                    if(k==S[j].size()){
                        //OK=0; 
                        break;
                    }

                }
            }
        }
        auto p=D.scc();
        if(p.size()!=26)OK=0;
        cout<<(OK?"yes":"no")<<endl;
    }
}
accuracy: 1
time_ms: 20
memory_kb: 5168
final_rank: 15

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

//関数版トポロジカルソート
vector<int> top_sort(vector<vector<int>> &G){
  vector<int> ret;
  int n = G.size();
  vector<int> in(n);
  for(int i=0; i<n; i++){
    for(int j=0; j<G[i].size(); j++){
      in[G[i][j]]++;
    }
  }
  queue<int> Q;
  for(int i=0; i<n; i++){
    if(in[i] == 0){
      Q.push(i);
      ret.push_back(i);
    }
  }
  while(Q.size()){
    int x = Q.front();
    Q.pop();
    for(int i=0; i<G[x].size(); i++){
      in[G[x][i]]--;
      if(in[G[x][i]] == 0){
        Q.push(G[x][i]);
        ret.push_back(G[x][i]);
      }
    }
  }
  return ret;
}

void solve(int N){
  vector<string> vec(N);
  for(int i=0; i<N; i++){
    cin >> vec[i];
  }
  vector<vector<int>> G(26,vector<int>(0));
  for(int i=0; i<N; i++){
    for(int j=i+1; j<N; j++){
      if(vec[i] == vec[j]){
        continue;
      }
      for(int k=0; k<vec[i].size(); k++){
        if(vec[j].size() <= k){
          cout << "no" << endl;
          return;
        }
        if(vec[i][k] != vec[j][k]){
          int x = vec[i][k] - 'a';
          int y = vec[j][k] - 'a';
          G[x].push_back(y);
          break;
        }
      }
    }
  }
  vector<int> T = top_sort(G);
  if(T.size() == 26){
    cout << "yes" << endl;
  }
  else{
    cout << "no" << endl;
  }
}

int main(){
  while(true){
    int N;
    cin >> N;
    if(N == 0){
      break;
    }
    solve(N);
    //break;
  }
}
accuracy: 1
time_ms: 20
memory_kb: 4208
final_rank: 11

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

int n;
vector<string> s;

bool solve();

int main() {
  while (1) {
    cin >> n;
    if (!n) break;
    s.resize(n);
    for (auto &p : s) cin >> p;
    if (solve())
      cout << "yes" << endl;
    else
      cout << "no" << endl;
  }
  return 0;
}

bool solve() {
  {  // prefix
    for (int i = 0; i < n; ++i)
      for (int j = i + 1; j < n; ++j)
        if (s[i] != s[j] && s[i].size() > s[j].size()) {
          int len = s[j].size();
          if (s[i].substr(0, len) == s[j].substr(0, len)) return 0;
        }
  }
  vector<vector<set<int>>> memo(26, vector(26, set<int>()));
  for (int i = 0; i < n; ++i)
    for (int j = i + 1; j < n; ++j)
      if (s[i] != s[j]) {
        int len = min(s[i].size(), s[j].size());
        if (s[i].substr(0, len) == s[j].substr(0, len)) continue;
        for (int k = 0; k < len; ++k)
          if (s[i][k] != s[j][k]) {
            int idl = s[i][k] - 'a', idr = s[j][k] - 'a';
            memo[idl][idr].insert(1);
            memo[idr][idl].insert(0);
            if (memo[idl][idr].size() > 1) return 0;
            break;
          }
      }
  return 1;
}
accuracy: 1
time_ms: 30
memory_kb: 3468
final_rank: 7

code_snippet: #include <cmath>
#include <deque>
#include <algorithm>
#include <iterator>
#include <list>
#include <tuple>
#include <map>
#include <unordered_map>
#include <queue>
#include <set>
#include <unordered_set>
#include <stack>
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <functional>
#include <numeric>
#include <iomanip> 
#include <stdio.h>
#include <assert.h>
#include <cstring>
//eolibraries
#define lnf 3999999999999999999
#define inf 999999999
#define fi first
#define se second
#define pb push_back
#define ll long long
#define ld long double
#define all(c) (c).begin(),(c).end()
#define sz(c) (int)(c).size()
#define make_unique(a) sort(all(a)),a.erase(unique(all(a)),a.end())
#define pii pair <int,int>
#define rep(i,n) for(int i = 0 ; i < n ; i++) 
#define drep(i,n) for(int i = n-1 ; i >= 0 ; i--)
#define crep(i,x,n) for(int i = x ; i < n ; i++)
#define vi vector <int> 
#define vec(...) vector<__VA_ARGS__>
#define _37FuwZp ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0)
//eodefine
using namespace std;

const int mxn=1000;

int n;

void slv(){
	vec(string) a;
	rep(i,n){
		string s;
		cin>>s;
		a.pb(s);
	}
	bool pok=1;
	rep(i,n){
		crep(j,i+1,n){
			if(sz(a[i])>sz(a[j])){
				if(a[i].substr(0,sz(a[j]))==a[j]){ pok=0; break; }
			}
		}
	}
	vec(set<int>) adjo(27);
	vi deg(27,0);
	vi cand;
	rep(i,n){
		crep(j,i+1,n){
			rep(k,sz(a[i])){
				if(a[i][k]!=a[j][k]){
					int x=a[i][k]-'a',y=a[j][k]-'a';
					cand.pb(x);
					cand.pb(y);
					if(adjo[x].find(y)==adjo[x].end()) deg[y]++;
					adjo[x].insert(y);
					break;
				}
			}
		}
	}
	priority_queue<pii> pq;
	vi dp(27),usd(27,0);
	rep(i,26){
		if(!deg[i]) pq.push({0,i});
	}
	while(sz(pq)){
		pii top=pq.top();
		pq.pop();
		if(top.fi!=dp[top.se]) continue;
		int cost=top.fi,v=top.se;
		usd[v]=1;
		for(auto u : adjo[v]){
			if(usd[u] and dp[u]<cost){ pok=0; break; }
			deg[u]--;
		}
		for(auto u : adjo[v]){
			if(deg[u]==0 and dp[u]<cost+1){
				dp[u]=cost+1;
				pq.push({dp[u],u});
			}
		}
		if(!pok) break;
	}
	make_unique(cand);
	for(auto x : cand){
		if(usd[x]==0) pok=0;
	}
	puts(pok?"yes":"no");
}

int main(){
_37FuwZp;
	while(true){
		cin>>n;
		if(!n) break;
		slv();
	}
//	
	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 5096
final_rank: 16

code_snippet: #include <cmath>
#include <deque>
#include <algorithm>
#include <iterator>
#include <list>
#include <tuple>
#include <map>
#include <unordered_map>
#include <queue>
#include <set>
#include <unordered_set>
#include <stack>
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <functional>
#include <numeric>
#include <iomanip> 
#include <stdio.h>
#include <assert.h>
#include <cstring>
//eolibraries
#define lnf 3999999999999999999
#define inf 999999999
#define fi first
#define se second
#define pb push_back
#define ll long long
#define ld long double
#define all(c) (c).begin(),(c).end()
#define sz(c) (int)(c).size()
#define make_unique(a) sort(all(a)),a.erase(unique(all(a)),a.end())
#define pii pair <int,int>
#define rep(i,n) for(int i = 0 ; i < n ; i++) 
#define drep(i,n) for(int i = n-1 ; i >= 0 ; i--)
#define crep(i,x,n) for(int i = x ; i < n ; i++)
#define vi vector <int> 
#define vec(...) vector<__VA_ARGS__>
#define _37FuwZp ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0)
//eodefine
using namespace std;

const int mxn=1000;

int n;

void slv(){
	vec(string) a;
	rep(i,n){
		string s;
		cin>>s;
		a.pb(s);
		// cin>>a[i];
	}
	bool pok=1;
	rep(i,n){
		crep(j,i+1,n){
			if(sz(a[i])>sz(a[j])){
				if(a[i].substr(0,sz(a[j]))==a[j]){ pok=0; break; }
			}
		}
	}
	vec(set<int>) adjo(27);
	vi deg(27,0);
	vi cand;
	rep(i,n){
		crep(j,i+1,n){
			rep(k,sz(a[i])){
				if(a[i][k]!=a[j][k]){
					// if(i==0 and j==1){
					// // 	cout<<a[j][k]<<"\n";
					// // }
					int x=a[i][k]-'a',y=a[j][k]-'a';
					cand.pb(x);
					cand.pb(y);
					if(adjo[x].find(y)==adjo[x].end()) deg[y]++;
					adjo[x].insert(y);
					// adjo[(int)(a[i][k]-'a')].insert((int)(a[j][k]-'a'));
					break;
				}
			}
		}
	}
	priority_queue<pii> pq;
	vi dp(27),usd(27,0);
	rep(i,26){
		// if(i==1) cout<<deg[i]<<"\n";
		if(!deg[i]) pq.push({0,i});
	}
	while(sz(pq)){
		pii top=pq.top();
		pq.pop();
		if(top.fi!=dp[top.se]) continue;
		int cost=top.fi,v=top.se;
		// cout<<cost<<" "<<v<<"\n";
		usd[v]=1;
		for(auto u : adjo[v]){
			if(usd[u] and dp[u]<cost){ pok=0; break; }
			deg[u]--;
		}
		for(auto u : adjo[v]){
			if(deg[u]==0 and dp[u]<cost+1){
				dp[u]=cost+1;
				pq.push({dp[u],u});
			}
		}
		if(!pok) break;
	}
	make_unique(cand);
	for(auto x : cand){
		if(usd[x]==0) pok=0;
	}
	puts(pok?"yes":"no");
}

int main(){
_37FuwZp;
	while(true){
		cin>>n;
		if(!n) break;
		slv();
	}
//	
	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 5120
final_rank: 17

code_snippet: #include <cmath>
#include <deque>
#include <algorithm>
#include <iterator>
#include <list>
#include <tuple>
#include <map>
#include <unordered_map>
#include <queue>
#include <set>
#include <unordered_set>
#include <stack>
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <functional>
#include <numeric>
#include <iomanip> 
#include <stdio.h>
#include <assert.h>
#include <cstring>
//eolibraries
#define lnf 3999999999999999999
#define inf 999999999
#define fi first
#define se second
#define pb push_back
#define ll long long
#define ld long double
#define all(c) (c).begin(),(c).end()
#define sz(c) (int)(c).size()
#define make_unique(a) sort(all(a)),a.erase(unique(all(a)),a.end())
#define pii pair <int,int>
#define rep(i,n) for(int i = 0 ; i < n ; i++) 
#define drep(i,n) for(int i = n-1 ; i >= 0 ; i--)
#define crep(i,x,n) for(int i = x ; i < n ; i++)
#define vi vector <int> 
#define vec(...) vector<__VA_ARGS__>
#define _37FuwZp ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0)
//eodefine
using namespace std;

const int mxn=1000;

int n;

void slv(){
	vec(string) a;
	rep(i,n){
		string s;
		cin>>s;
		a.pb(s);
	}
	bool pok=1;
	rep(i,n){
		crep(j,i+1,n){
			if(sz(a[i])>sz(a[j])){
				if(a[i].substr(0,sz(a[j]))==a[j]){ pok=0; break; }
			}
		}
	}
	vec(set<int>) adjo(30);
	vi deg(30,0);
	vi cand;
	rep(i,n){
		crep(j,i+1,n){
			rep(k,sz(a[i])){
				if(a[i][k]!=a[j][k]){
					// if(i==0 and j==1){
					// // 	cout<<a[j][k]<<"\n";
					// // }
					int x=a[i][k]-'a',y=a[j][k]-'a';
					cand.pb(x);
					cand.pb(y);
					if(adjo[x].find(y)==adjo[x].end()) deg[y]++;
					adjo[x].insert(y);
					// adjo[(int)(a[i][k]-'a')].insert((int)(a[j][k]-'a'));
					break;
				}
			}
		}
	}
	priority_queue<pii> pq;
	vi dp(30),usd(30,0);
	rep(i,26){
		// if(i==1) cout<<deg[i]<<"\n";
		if(!deg[i]) pq.push({0,i});
	}
	while(sz(pq)){
		pii top=pq.top();
		pq.pop();
		if(top.fi!=dp[top.se]) continue;
		int cost=top.fi,v=top.se;
		// cout<<cost<<" "<<v<<"\n";
		usd[v]=1;
		for(auto u : adjo[v]){
			if(usd[u] and dp[u]<cost){ pok=0; break; }
			deg[u]--;
		}
		for(auto u : adjo[v]){
			if(deg[u]==0 and dp[u]<cost+1){
				dp[u]=cost+1;
				pq.push({dp[u],u});
			}
		}
		if(!pok) break;
	}
	make_unique(cand);
	for(auto x : cand){
		if(usd[x]==0) pok=0;
	}
	puts(pok?"yes":"no");
}

int main(){
_37FuwZp;
	while(true){
		cin>>n;
		if(!n) break;
		slv();
	}
//	
	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 5260
final_rank: 18

code_snippet: #pragma GCC optimize("Ofast")
#include <iostream> // cout, endl, cin
#include <string> // string, to_string, stoi
#include <vector> // vector
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <utility> // pair, make_pair
#include <tuple> // tuple, make_tuple
#include <cstdint> // int64_t, int*_t
#include <cstdio> // printf
#include <map> // map
#include <queue> // queue, priority_queue
#include <set> // set
#include <stack> // stack
#include <deque> // deque
#include <unordered_map> // unordered_map
#include <unordered_set> // unordered_set
#include <bitset> // bitset
#include <cctype> // isupper, islower, isdigit, toupper, tolower
#include <iomanip> // setprecision
#include <complex> // complex
#include <math.h> 
#include <functional>
#include <cassert>
using namespace std;
using ll = long long;
using P = pair<int,int>;
constexpr ll INF = 1e18;
constexpr ll LLMAX = 9223372036854775807;
constexpr int inf = 1e9;
constexpr ll mod = 1000000007;
constexpr ll mod2 = 998244353;
const int dx[8] = {1, 0, -1, 0,1,1,-1,-1};
const int dy[8] = {0, 1, 0, -1,1,-1,1,-1};
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
// ---------------------------------------------------------------------------


bool solve(){
  int N;
  cin >> N;
  if(N == 0) return false;
  vector<string> G(N);
  for(int i=0; i<N; i++) cin >> G[i];
  bool can = true;
  for(int i=0; i<N; i++){
    for(int j=i+1; j<N; j++){
      if(G[i].size() > G[j].size()){
        if(G[i].substr(0,G[j].size()) == G[j]) can = false;
      }
    }
  }
  vector<vector<int>> alpha(26);
  for(int i=0; i<N; i++){
    for(int j=i+1; j<N; j++){
      for(int d=0; d<min(G[i].size(),G[j].size()); d++){
        if(G[i][d] != G[j][d]){
          alpha[G[i][d]-'a'].emplace_back(G[j][d]-'a');
          break;
        }
      }
    }
  }
  vector<int> dist(26,0);
  for(int i=0; i<1000; i++){
    for(int v=0; v<26; v++){
      for(int nv: alpha[v]){
        chmax(dist[nv],dist[v] + 1);
      }
    }
  }
  for(int v=0; v<26; v++){
    for(int nv: alpha[v]){
      if(chmax(dist[nv],dist[v] + 1)){
        can = false;
      }
    }
  }
  cout << (can ? "yes\n" : "no\n");
  return true;
}

int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  while(solve());
  return 0;
}
accuracy: 1
time_ms: 1980
memory_kb: 4236
final_rank: 20

code_snippet: #pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <iostream>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <unordered_map>
#include <map>
#include <set>
#include <algorithm>
#include <queue>
#include <stack>
#include <functional>
#include <bitset>
#include <assert.h>
#include <unordered_map>
#include <fstream>
#include <ctime>
#include <complex>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = 1<<30;
const ll linf = 1LL<<62;
const int MAX = 510000;
ll dy[8] = {0,1,0,-1,1,-1,-1,1};
ll dx[8] = {1,0,-1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-10;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << "debug: " << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << "debug: " << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
const int mod = 1e9 + 7;
//const int mod = 998244353;

int main(){
	while(1){
		int n; cin >> n;
		if(!n) break;
		vector<string> s(n);
		rep(i,n) cin >> s[i];
		int G[26][26] = {};
		bool yes = true;
		rep(i,n){
			REP(j,i+1,n){
				bool exist = false;
				rep(k,min(s[i].size(), s[j].size())){
					if(s[i][k] != s[j][k]){
						G[s[i][k]-'a'][s[j][k]-'a'] = 1;
						exist = true;
						break;
					}
				}
				if(!exist){
					if(s[i] > s[j]) yes = false;
				}
			}
		}
		vector<int> indeg(26,0);
		rep(i,26) rep(j,26){
			indeg[j] += G[i][j];
		}
		queue<int> q;
		vector<int> d(26,inf);
		rep(i,26){
			if(!indeg[i]) q.push(i), d[i] = 0;
		}
		while(!q.empty()){
			int u = q.front(); q.pop();
			rep(v,26){
				if(G[u][v] && d[v] < d[u]){
					yes = false;
					break;
				}else if(G[u][v]){
					d[v] = d[u] + 1;
					indeg[v]--;
					if(!indeg[v]) q.push(v);
				}
			}
			if(!yes) break;
		}
		if(yes && *max_element(all(indeg)) == 0) cout << "yes" << "\n";
		else cout << "no" << "\n";
	}
}
accuracy: 1
time_ms: 20
memory_kb: 3112
final_rank: 3

code_snippet: #include <stdio.h>
#include <bits/stdc++.h>

#include <algorithm>

#include <algorithm>
#include <utility>
#include <vector>

namespace atcoder {
namespace internal {

template <class E> struct csr {
    std::vector<int> start;
    std::vector<E> elist;
    csr(int n, const std::vector<std::pair<int, E>>& edges)
        : start(n + 1), elist(edges.size()) {
        for (auto e : edges) {
            start[e.first + 1]++;
        }
        for (int i = 1; i <= n; i++) {
            start[i] += start[i - 1];
        }
        auto counter = start;
        for (auto e : edges) {
            elist[counter[e.first]++] = e.second;
        }
    }
};

// Reference:
// R. Tarjan,
// Depth-First Search and Linear Graph Algorithms
struct scc_graph {
  public:
    scc_graph(int n) : _n(n) {}

    int num_vertices() { return _n; }

    void add_edge(int from, int to) { edges.push_back({from, {to}}); }

    // @return pair of (# of scc, scc id)
    std::pair<int, std::vector<int>> scc_ids() {
        auto g = csr<edge>(_n, edges);
        int now_ord = 0, group_num = 0;
        std::vector<int> visited, low(_n), ord(_n, -1), ids(_n);
        visited.reserve(_n);
        auto dfs = [&](auto self, int v) -> void {
            low[v] = ord[v] = now_ord++;
            visited.push_back(v);
            for (int i = g.start[v]; i < g.start[v + 1]; i++) {
                auto to = g.elist[i].to;
                if (ord[to] == -1) {
                    self(self, to);
                    low[v] = std::min(low[v], low[to]);
                } else {
                    low[v] = std::min(low[v], ord[to]);
                }
            }
            if (low[v] == ord[v]) {
                while (true) {
                    int u = visited.back();
                    visited.pop_back();
                    ord[u] = _n;
                    ids[u] = group_num;
                    if (u == v) break;
                }
                group_num++;
            }
        };
        for (int i = 0; i < _n; i++) {
            if (ord[i] == -1) dfs(dfs, i);
        }
        for (auto& x : ids) {
            x = group_num - 1 - x;
        }
        return {group_num, ids};
    }

    std::vector<std::vector<int>> scc() {
        auto ids = scc_ids();
        int group_num = ids.first;
        std::vector<int> counts(group_num);
        for (auto x : ids.second) counts[x]++;
        std::vector<std::vector<int>> groups(ids.first);
        for (int i = 0; i < group_num; i++) {
            groups[i].reserve(counts[i]);
        }
        for (int i = 0; i < _n; i++) {
            groups[ids.second[i]].push_back(i);
        }
        return groups;
    }

  private:
    int _n;
    struct edge {
        int to;
    };
    std::vector<std::pair<int, edge>> edges;
};

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <vector>

namespace atcoder {

struct scc_graph {
  public:
    scc_graph() : internal(0) {}
    scc_graph(int n) : internal(n) {}

    void add_edge(int from, int to) {
        int n = internal.num_vertices();
        assert(0 <= from && from < n);
        assert(0 <= to && to < n);
        internal.add_edge(from, to);
    }

    std::vector<std::vector<int>> scc() { return internal.scc(); }

  private:
    internal::scc_graph internal;
};

}  // namespace atcoder

using namespace atcoder;
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define Inf 1000000000

int main(){
	
	while(true){
		int n;
		cin>>n;
		if(n==0)break;
		vector<string> s(n);
		rep(i,n)cin>>s[i];
		bool f = true;
		for(int i=0;i<n;i++){
			for(int j=i+1;j<n;j++){
				if(s[i].size()<=s[j].size())continue;
				if(s[i].substr(0,s[j].size())==s[j]){
					f=false;
					break;
				}
			}
		}
		
		scc_graph S(26);
		for(int i=0;i<n;i++){
			for(int j=i+1;j<n;j++){
				for(int k=0;k<min(s[i].size(),s[j].size());k++){
					if(s[i][k]!=s[j][k]){
						int u = s[i][k]-'a';
						int v = s[j][k]-'a';
						S.add_edge(u,v);
						break;
					}
				}
			}
		}
		
		if(S.scc().size()!=26)f=false;
		
		if(f)cout<<"yes"<<endl;
		else cout<<"no"<<endl;
		
	}
	
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 5052
final_rank: 14

code_snippet: #include <bits/stdc++.h>
#define For(i, a, b) for(int (i)=(int)(a); (i)<(int)(b); ++(i))
#define rFor(i, a, b) for(int (i)=(int)(a)-1; (i)>=(int)(b); --(i))
#define rep(i, n) For((i), 0, (n))
#define rrep(i, n) rFor((i), (n), 0)
#define fi first
#define se second
using namespace std;
typedef long long lint;
typedef unsigned long long ulint;
typedef pair<int, int> pii;
typedef pair<lint, lint> pll;
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(a>b){a=b; return true;} return false;}
template<class T> T div_floor(T a, T b){
    if(b < 0) a *= -1, b *= -1;
    return a>=0 ? a/b : (a+1)/b-1;
}
template<class T> T div_ceil(T a, T b){
    if(b < 0) a *= -1, b *= -1;
    return a>0 ? (a-1)/b+1 : a/b;
}

constexpr lint mod = 1000000007;
constexpr lint INF = mod * mod;
constexpr int MAX = 200010;

template<typename T> struct edge{
    int from, to; T cost;
    edge(int f, int t, T c): from(f), to(t), cost(c){}
};
 
template<typename T> struct Graph{
    vector<vector<edge<T>>> G;
    int n;
 
    Graph(int n_): n(n_){
        G.resize(n);
    }
 
    void add_edge(int f, int t, T c){
        G[f].emplace_back(f, t, c);
    }
};

template<typename T> 
pair<bool, vector<int>> topological_sort(Graph<T> &gr){
    vector<int> ret(gr.n, -1), in(gr.n, 0);
    rep(i, gr.n)for(edge<T> &e: gr.G[i]) ++in[e.to];
    int cur = 0;
    stack<int> st;
    rep(i, gr.n)if(!in[i]) st.push(i);
    if(st.empty()) return make_pair(false, ret);
    while(!st.empty()){
        int v = st.top(); st.pop();
        ret[cur++] = v;
        for(edge<T> &e: gr.G[v]){
            if(!in[e.to]) return make_pair(false, ret);
            --in[e.to];
            if(!in[e.to]) st.push(e.to);
        }
    }
    return make_pair(cur == gr.n, ret);
}

template<typename T>
bool has_cycle(Graph<T> &gr){
    return !topological_sort(gr).fi;
}

int n;

void solve(){
    string s[n];
    rep(i, n) cin >> s[i];
    Graph<int> gr(26);
    bool adj[26][26];
    rep(i, 26)rep(j, 26) adj[i][j] = false;
    rep(i, n)For(j, i+1, n){
        if(s[i] == s[j]) continue;
        if(s[i].substr(0, s[j].size()) == s[j]){
            puts("no");
            return;
        }
        rep(k, 20)if(s[i][k] != s[j][k]){
            int x = s[i][k] - 'a', y = s[j][k] - 'a';
            if(!adj[x][y]){
                gr.add_edge(x, y, 1);
                adj[x][y] = true;
            }
            break;
        }
    }
    puts(!has_cycle(gr) ? "yes" : "no");
}

int main(){
    while(scanf("%d", &n) && n){
        solve();
    }
}
accuracy: 1
time_ms: 110
memory_kb: 3308
final_rank: 6

code_snippet: /* monkukui 競技プログラミング用のテンプレート  (ここから) */
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using lint = long long int;
using ll = long long int;
using lnt = long long int;
using graph = vector<vector<int>>;
using wgraph = vector<vector<pair<int, long long int>>>;
long long int INF = 1001001001001001LL;
int inf = 100100100;
long long int MOD = 1000000007LL;
double PI = 3.1415926535897932;
long long int di[] = {-1, 0, 1, 0, -1, 1, 1, -1};
long long int dj[] = {0, 1, 0, -1, 1, 1, -1, -1};

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}

#define rep(i,n) for(int i = 0; i < (n); i++)
#define rrep(i,n) for(int i = 1; i <= (n); i++)
#define drep(i,n) for(int i = (n)-1; i >= 0; i--)
#define srep(i,s,t) for(int i = s; i < t; i++)
#define all(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()
#define pb push_back

/* monkukui 競技プログラミング用のテンプレート (ここまで)*/

struct StronglyConnectedComponents {
public:
  const int n;
  vector<bool> isthrough;
  vector<int> vs, cmp;
  vector< vector<int> > G, rG, H; // グラフ、逆辺グラフ、縮約後のグラフ

  StronglyConnectedComponents(vector<vector<int>> &g) :
    n(g.size()), isthrough(n, false), cmp(n, 0), G(n), rG(n) {
    for(int i = 0; i < n; i++) {
      for(size_t j = 0; j < g[i].size(); j++) {
        G[i].push_back(g[i][j]);
        rG[g[i][j]].push_back(i);
      }
    }
  }

  void SccDfsOne(int cur) {
    isthrough[cur] = true;
    for(size_t i = 0; i < G[cur].size(); i++) {
      if(!isthrough[G[cur][i]]) {
        SccDfsOne(G[cur][i]);
      }
    }
    vs.push_back(cur);
  }

  void SccDfsTwo(vector<int> &vec, int cur, int k) {
    cmp[cur] = k;
    isthrough[cur] = true;
    vec.push_back(cur);
    for(size_t i = 0; i < rG[cur].size(); i++) {
      if(!isthrough[rG[cur][i]]) {
        SccDfsTwo(vec, rG[cur][i], k);
      }
    }
  }

  // 縮約後のグループ、グループ数
  pair<vector<int>, int> scc() {
    // 1回めのDFS
    for(int i = 0; i < n; i++)
      if(!isthrough[i]) SccDfsOne(i);

    fill(isthrough.begin(), isthrough.end(), false);
    reverse(vs.begin(), vs.end());
    int k = 0; vector<vector<int>> S;

    // 2回めのDFS
    for(size_t i = 0; i < vs.size(); i++) {
      if(!isthrough[vs[i]]) {
        S.push_back(vector<int>());
        SccDfsTwo(S.back(), vs[i], k++);
      }
    }

    H.resize(k);
    fill(isthrough.begin(), isthrough.end(), false);
    for(size_t i = 0; i < k; i++) {
      for(size_t j = 0; j < S[i].size(); j++) {
        int v = S[i][j];
        for(size_t x = 0; x < G[v].size(); x++) {
          int u = G[v][x];
          if(isthrough[cmp[u]] or cmp[v] == cmp[u]) continue;
          isthrough[cmp[u]] = true;
          H[cmp[v]].push_back(cmp[u]);
        }
      }
      for(size_t j=0; j<H[i].size(); j++) isthrough[H[i][j]] = false;
    }
    return make_pair(cmp, k);
  }
};

// 閉路があるか
bool func(graph g) {
  
  StronglyConnectedComponents scc(g);
  auto hoge = scc.scc();
  return (hoge.second != g.size());
  return false;
}

int main(){
  
  while(1) {
    int n; cin >> n;
    if(n == 0) break;
    vector<string> vs(n);
    for(int i = 0; i < n; i++) {
      cin >> vs[i];
      vs[i] = vs[i] + '#';
    }

    graph g(26);

    bool flag = false;
    for(int i = 0; i < n; i++) {
      for(int j = i + 1; j < n; j++) {
        int u = -1;
        int v = -1;
        if(vs[i] == vs[j]) continue;

        for(int k = 0; k < min(vs[i].size(), vs[j].size()); k++) {
          if(vs[i][k] == vs[j][k]) continue;

          // 不一致
          if(vs[i][k] == '#') continue;
          if(vs[j][k] == '#') {
            cout << "no" << endl;
            i += n;
            j += n;
            flag = true;
            break;
          }

          u = vs[i][k] - 'a';
          v = vs[j][k] - 'a';

          // u -> v
          g[u].push_back(v);
          break;
        }
      }
    }

    if(flag) continue;

    if(func(g)) cout << "no" << endl;
    else        cout << "yes" << endl;

  }
  return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 5792
final_rank: 19

code_snippet: #include <cstdio>
#include <cstdint>
#include <vector>
#include <utility>
#include <algorithm>
#include <queue>
#include <string>
#include <tuple>

bool includes(std::string const& s, std::string const& t) {
  // s == "ab", t == "a"  => true
  // s == "a",  t == "a"  => false
  // s == "a",  t == "ab" => false
  if (s.length() <= t.length()) return false;
  return (s.compare(0, t.length(), t) == 0);
}

std::pair<char, char> critical(std::string const& s, std::string const& t) {
  size_t n = std::min(s.length(), t.length());
  for (size_t i = 0; i <= n; ++i) {
    if (s[i] == t[i]) continue;
    if (s[i] == 0 || t[i] == 0) return {0, 0};  // no constraints
    return {s[i]-'a', t[i]-'a'};
  }
  return {0, 0};  // no constraints
}

int testcase_ends() {
  size_t n;
  scanf("%zu", &n);
  if (n == 0) return 1;

  std::vector<std::string> s(n);
  for (size_t i = 0; i < n; ++i) {
    char buf[16];
    scanf("%s", buf);
    s[i] = buf;
  }

  size_t sigma = 26;
  std::vector<std::vector<int>> g0(sigma, std::vector<int>(sigma));

  for (size_t i = 0; i < n; ++i)
    for (size_t j = i+1; j < n; ++j) {
      size_t lc, gc;
      if (includes(s[i], s[j])) return puts("no"), 0;
      std::tie(lc, gc) = critical(s[i], s[j]);
      g0[lc][gc] = 1;
    }

  std::vector<std::vector<size_t>> g(sigma);
  std::vector<size_t> indeg(sigma);
  for (size_t i = 0; i < sigma; ++i)
    for (size_t j = 0; j < sigma; ++j)
      if (i != j && g0[i][j]) {
        g[i].push_back(j);
        // fprintf(stderr, "%c -> %c\n", char(i+'a'), char(j+'a'));
        ++indeg[j];
      }

  std::queue<size_t> q;
  for (size_t i = 0; i < sigma; ++i)
    if (indeg[i] == 0) q.push(i);

  while (!q.empty()) {
    size_t v = q.front();
    // fprintf(stderr, "pop: %c\n", char(v+'a'));
    q.pop();
    for (auto u: g[v]) {
      // fprintf(stderr, "reached: %c\n", char(u+'a'));
      if (--indeg[u] == 0) q.push(u);
    }
  }

  if (*std::max_element(indeg.begin(), indeg.end()) != 0) {
    puts("no");
  } else {
    puts("yes");
  }
  return 0;
}

int main() {
  while (!testcase_ends()) {}
}
accuracy: 1
time_ms: 10
memory_kb: 2660
final_rank: 1

code_snippet: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int INF = 1e9;
const ll LINF = 1e18;
inline ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
inline ll lcm(ll a, ll b) { return a / gcd(a, b)*b; }
template<class S,class T> ostream& operator << (ostream& out,const pair<S,T>& o){ out << "(" << o.first << "," << o.second << ")"; return out; }
template<class T> ostream& operator << (ostream& out,const vector<T>& V){ for(int i = 0; i < V.size(); i++){ out << V[i]; if(i!=V.size()-1) out << " ";} return out; }
template<class T> ostream& operator << (ostream& out,const vector<vector<T> >& Mat){ for(int i = 0; i < Mat.size(); i++) { if(i != 0) out << endl; out << Mat[i];} return out; }
template<class S,class T> ostream& operator << (ostream& out,const map<S,T>& mp){ out << "{ "; for(auto it = mp.begin(); it != mp.end(); it++){ out << it->first << ":" << it->second; if(mp.size()-1 != distance(mp.begin(),it)) out << ", "; } out << " }"; return out; }
template<typename T>vector<T> make_v(size_t a){return vector<T>(a);}
template<typename T,typename... Ts>auto make_v(size_t a,Ts... ts){return vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));}
template<typename T,typename V> typename enable_if<is_class<T>::value==0>::type fill_v(T &t,const V &v){t=v;}
template<typename T,typename V> typename enable_if<is_class<T>::value!=0>::type fill_v(T &t,const V &v){for(auto &e:t) fill_v(e,v);}
/*
 <url:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2534>
 問題文============================================================
 =================================================================
 解説=============================================================
 ================================================================
 */

int n;
template<class Type>
Type solve(Type res = Type()){
    while(cin >> n,n){
        // preprocessing
        vector<string> s(n);
        for(auto& in:s) cin >> in;
        
        for(auto& each_s:s){
            each_s += string(10-each_s.length(),(char)('a'-1));
            for(auto& c:each_s) c -= 'a'-1;
        }
        // main processing
        bool ok = true;
        int dist[27][27] = {0};
        for(int i = 0; i < n;i++){
            for(int j = i+1; j < n; j++){
                int k = 0;
                while(k<10&&s[i][k]==s[j][k]) k++;
                if(k==10) continue;
                if(dist[s[j][k]][s[i][k]]) ok = false;
                dist[s[i][k]][s[j][k]] = 1;
            }
        }
        for(int i = 0; i < 27;i++) if(dist[i][0]) ok = false;
        
        if(!ok){
            cout << "no" << endl;
            continue;
        }
        
        function<bool(int,int)> rec = [&](int k,int cnt){
            if(cnt >= 27) return false;
            bool f = true;
            for(int i = 0; i < 27;i++){
                if(dist[k][i]) f = false;
            }
            if(f) return true;
            
            f = true;
            for(int i = 0; i < 27;i++){
                if(dist[k][i]){
                    f &= rec(i,cnt+1);
                }
            }
            return f;
        };
        
        if(rec(0,0)) cout << "yes" << endl;
        else cout << "no" << endl;
    }
    return res;
}
int main(void) {
    cin.tie(0); ios_base::sync_with_stdio(false);
    solve(0);
    //cout << fixed << setprecision(15) << solve<ll>() << endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3076
final_rank: 2

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

#define rep(i, n) for(int i = 0; i < (n); i++)
#define repp(i, l, r) for(int i = (l); i < (r); i++)
#define per(i, n) for(int i = ((n)-1); i >= 0; i--)
#define perr(i, l, r) for(int i = ((r)-1); i >= (l); i--)
#define all(x) (x).begin(),(x).end()
#define MOD 1000000007
#define IINF 1000000000
#define LINF 1000000000000000000
#define SP <<" "<<
#define CYES cout<<"Yes"<<endl
#define CNO cout<<"No"<<endl
#define CFS cin.tie(0);ios::sync_with_stdio(false)

typedef long long LL;
typedef long double LD;

int main(){
  while(1){
    int n;
    cin >> n;
    if(n==0) return 0;
    vector<vector<int>> e(26);
    vector<int> deg(26,0);
    vector<string> s(n);
    queue<int> q;
    rep(i,n){
      cin >> s[i];
    }
    rep(i,n){
      rep(j,i){
        rep(k,min(s[i].length(),s[j].length())){
          if(s[i][k]!=s[j][k]){
            e[s[j][k]-'a'].push_back(s[i][k]-'a');
            deg[s[i][k]-'a']++;
            goto next;
          }
        }
        if(s[i].length()<s[j].length()){
          cout << "no" << endl;
          goto nextt;
        }
        next:;
      }
    }
    rep(i,26) if(deg[i]==0) q.push(i);
    while(!q.empty()){
      int now = q.front();
      q.pop();
      for(auto nx:e[now]){
        deg[nx]--;
        if(deg[nx]==0) q.push(nx);
      }
    }
    rep(i,26){
      if(deg[i]!=0){
        cout << "no" << endl;
        goto nextt;
      }
    }
    cout << "yes" << endl;
    nextt:;
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 4156
final_rank: 10

code_snippet: #include "bits/stdc++.h"

#define REP(i,n) for(ll i=0;i<ll(n);++i)
#define RREP(i,n) for(ll i=ll(n)-1;i>=0;--i)
#define FOR(i,m,n) for(ll i=m;i<ll(n);++i)
#define RFOR(i,m,n) for(ll i=ll(n)-1;i>=ll(m);--i)
#define ALL(v) (v).begin(),(v).end()
#define UNIQUE(v) v.erase(unique(ALL(v)),v.end());
#define INF 1000000001ll
#define MOD 1000000007ll
#define EPS 1e-9

constexpr int dx[8] = { 1,1,0,-1,-1,-1,0,1 };
constexpr int dy[8] = { 0,1,1,1,0,-1,-1,-1 };


using namespace std;

using ll = long long;
using vi = vector<int>;
using vl = vector<ll>;
using vvi = vector<vi>;
using vvl = vector<vl>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

template <class T> bool chmin(T& a, const T& b) { if (a > b) { a = b; return true; } return false; }
template <class T> bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; } return false; }
bool ok = true;
void dfs(vvi& g, vi &visited,int i) {
	if (!ok)return;
	if (visited[i])ok = false;
	visited[i] = 1;
	REP(j, g[i].size())dfs(g, visited, g[i][j]);
	visited[i] = 0;
}
int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int n;
	while (cin >> n, n) {
		vector<string> v(n);
		REP(i, n)cin >> v[i];
		vvi g(26);
		ok = true;
		REP(i, n - 1) {
			bool done = false;
			REP(j, min(v[i].size(), v[i + 1].size())) {

				if (v[i][j] != v[i + 1][j]) {
					done = true;
					g[v[i][j] - 'a'].push_back(v[i + 1][j] - 'a');
					break;
				}
			}
			if (!done) {
				if (v[i].size() > v[i + 1].size())ok = false;
			}
		}
		REP(i, 26) {
			sort(ALL(g[i]));
			UNIQUE(g[i]);
		}
		vi visited(26, 0);
		REP(i, 26) {
			REP(j, 26)visited[j] = 0;
			dfs(g, visited, i);
		}
		if (ok)cout << "yes" << endl;
		else cout << "no" << endl;
	}
}
accuracy: 1
time_ms: 240
memory_kb: 3152
final_rank: 9

code_snippet: #define _GLIBCXX_DEBUG
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cctype>
#include<math.h>
#include<string>
#include<string.h>
#include<stack>
#include<queue>
#include<vector>
#include<utility>
#include<set>
#include<map>
#include<stdlib.h>
#include<iomanip>
#include<deque>

using namespace std;

#define ll long long
#define ld long double
#define EPS 0.0000000001
#define INF 1e9
#define LINF (ll)INF*INF
#define MOD 1000000007
#define rep(i,n) for(int i=0;i<(n);i++)
#define loop(i,a,n) for(int i=a;i<(n);i++)
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)

#define int ll //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int,int> pii;
typedef vector<pii> vp;
typedef deque<int> di;

int gcd(int a, int b){
    if(b==0) return a;
    return gcd(b,a%b);
}
int lcm(int a, int b){
    return a*b/gcd(a,b);
}

signed main(void) {
    int n;
    while(cin >> n, n){
        vs s(n);
        rep(i,n)cin >> s[i];
        vector<vi> g(26);
        bool ans = true;
        rep(i,n-1){
            int j = 0;
            while(j < s[i].size() && j < s[i+1].size() && s[i][j] == s[i+1][j])j++;
            if(j == s[i+1].size() && j < s[i].size()){
                ans = false;
                break;
            }
            if(j == s[i].size() || j == s[i+1].size())continue;
            //cout << s[i][j] << " " << s[i+1][j] << endl;
            g[s[i][j]-'a'].push_back(s[i+1][j]-'a');
        }
        rep(i,26){
            queue<int> q;
            rep(j,g[i].size())q.push(g[i][j]);
            vi used(26);
            while(q.size() && ans){
                int v = q.front();
                q.pop();
                used[v]++;
                rep(j,g[v].size()){
                    int ne = g[v][j];
                    if(ne == i){
                        ans = false;
                    }
                    if(used[ne] == 0){
                        q.push(ne);
                    }
                }
            }
        }
        if(ans)cout << "yes" << endl;
        else cout << "no" << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3268
final_rank: 4

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

int main(){
    int N;
    while(cin>>N,N){
        vector<string> S(N);
        for(auto &s:S) cin>>s;
        int G[26][26];
        fill(G[0],G[26],0);
        bool flag=true;
        for(int i=0;i<N;i++){
            for(int j=i+1;j<N;j++){
                string s1=S[i], s2=S[j];
                if(s1==s2) continue;
                int ite=0;
                while(ite<min(s1.size(),s2.size())&&s1[ite]==s2[ite]) ite++;
                if(ite==s1.size()) continue;
                if(ite==s2.size()){
                    flag=false;
                    continue;
                }
                G[s1[ite]-'a'][s2[ite]-'a']=1;
            }
        }
        for(int k=0;k<26;k++){
            for(int i=0;i<26;i++){
                for(int j=0;j<26;j++){
                    G[i][j]|=G[i][k]&G[k][j];
                }
            }
        }
        for(int i=0;i<26;i++){
            if(G[i][i]) flag=false;
        }
        cout<<(flag?"yes":"no")<<endl;
    }

    return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 3208
final_rank: 8