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`.

Example

Input

4
cba
cab
b
a
3
bca
ab
a
5
abc
acb
b
c
c
5
abc
acb
c
b
b
0


Output

yes
no
yes
no
#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();
    }
}
