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 REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)

using namespace std;

typedef pair<int,int> ii;

vector<int> G[510];

vector<string> arr;
vector<ii> edges;
bool found[510];
bool used[510];
bool cycle;

bool inValid(string a,string b) {
  if( a == b ) return false;
  int diff = -1;
  rep(i,min(a.size(),b.size())) if( a[i] != b[i] ) { diff = i; break; }
  if( diff == -1 && a.size() > b.size() ) return true;
  return false;
}

void add(string a,string b){
  if( a == b ) return;
  int diff = -1;
  rep(i,min(a.size(),b.size())) if( a[i] != b[i] ) { diff = i; break; }
  if( diff == -1 ) return;
  edges.push_back(ii(a[diff]-'a',b[diff]-'a'));
}

bool visit(int v,vector<int>& order,vector<int>& color){
  color[v] = 1;
  rep(i,G[v].size()){
    int e = G[v][i];
    if(color[e] == 2)continue;
    if(color[e] == 1)return false;
    if(!visit(e,order,color))return false;
    }
  order.push_back(v);
  color[v] = 2;
  return true;
}

bool topologicalSort(vector<int>& order){
  vector<int> color(26,0); 
  for(int u=0;u<26;u++) if(!color[u] && !visit(u,order,color)) return false;
  reverse(order.begin(),order.end());
  return true;
}


int main(){
  int n;
  while(cin >> n,n){
    rep(i,510) { G[i].clear(); found[i] = used[i] = false;  }
    bool fin = false;
    cycle = false;
    arr.clear();
    arr.resize(n);
    edges.clear();
    rep(i,n) cin >> arr[i];
    rep(i,n-1) {
      if( inValid(arr[i],arr[i+1]) ) { puts("no"); fin = true; break; }
      add(arr[i],arr[i+1]);
    }
    if( fin ) continue;
    rep(i,edges.size()) {
      int src = edges[i].first;
      int dst = edges[i].second;
      G[src].push_back(dst);
    }
    vector<int> order;
    if( !topologicalSort(order) ) { puts("no"); continue; }
    puts("yes");
  }
  return 0;
}

// same as http://codeforces.com/contest/512/problem/A 