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

Solution in JAVA (judge verdict: Accepted)

import java.util.Scanner;

public class Main {

	static Scanner sc = new Scanner(System.in);
	static String[] str;
	static int N;
	static boolean[][] g;

	public static void main(String[] args) throws Exception {
		while (true) {
			N = sc.nextInt();
			if (N == 0) break;
			str = new String[N];
			for (int i = 0; i < N; ++i) {
				str[i] = sc.next();
			}
			System.out.println(solve() ? "yes" : "no");
		}
	}

	static boolean solve() {
		g = new boolean[26][26];
		if (!construct(0, N, 0)) {
			return false;
		}
		for (int i = 0; i < 26; ++i) {
			boolean[] visited = new boolean[26];
			if (!dfs(i, visited)) {
				return false;
			}
		}
		return true;
	}

	static boolean dfs(int pos, boolean[] visited) {
		if (visited[pos]) return false;
		visited[pos] = true;
		for (int i = 0; i < 26; ++i) {
			if (g[pos][i]) {
				if (!dfs(i, visited)) {
					return false;
				}
			}
		}
		visited[pos] = false;
		return true;
	}

	static boolean construct(int s, int e, int pos) {
		// System.out.println(s + " " + e + " " + pos);
		if (e - s == 1) return true;
		while (s < e && str[s].length() == pos) {
			++s;
		}
		if (s >= e - 1) return true;
		int prev = s;
		for (int i = s + 1;; ++i) {
			if (i == e) {
				if (!construct(prev, i, pos + 1)) {
					return false;
				}
				break;
			}
			if (str[i].length() == pos) {
				return false;
			}
			if (str[i].charAt(pos) != str[prev].charAt(pos)) {
				g[str[prev].charAt(pos) - 'a'][str[i].charAt(pos) - 'a'] = true;
				// System.out.println(s + " " + e + " " + pos + " " + str[prev].charAt(pos) + " " + str[i].charAt(pos));
				if (!construct(prev, i, pos + 1)) {
					return false;
				}
				prev = i;
			}
		}
		return true;
	}

}