You are given n strings. Each string consists of lowercase English letters. Rearrange (reorder) the given strings in such a way that for every string, all strings that are placed before it are its substrings.

String a is a substring of string b if it is possible to choose several consecutive letters in b in such a way that they form a. For example, string "for" is contained as a substring in strings "codeforces", "for" and "therefore", but is not contained as a substring in strings "four", "fofo" and "rof".

Input

The first line contains an integer n (1 ≤ n ≤ 100) — the number of strings.

The next n lines contain the given strings. The number of letters in each string is from 1 to 100, inclusive. Each string consists of lowercase English letters.

Some strings might be equal.

Output

If it is impossible to reorder n given strings in required order, print "NO" (without quotes).

Otherwise print "YES" (without quotes) and n given strings in required order.

Examples

Input

5
a
aba
abacaba
ba
aba


Output

YES
a
ba
aba
aba
abacaba


Input

5
a
abacaba
ba
aba
abab


Output

NO


Input

3
qwerty
qwerty
qwerty


Output

YES
qwerty
qwerty
qwerty

Note

In the second example you cannot reorder the strings because the string "abab" is not a substring of the string "abacaba".
// Code Author: Shrey Shah
    // Institute : DA-IICT
    // Quote : Think twice , Code Once
 
import java.io.*;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;



 public class Tester1{

    static double eps=(double)1e-6;
    static long mod=(long)1e9+7;
    static int length = (int)1e6;
    static long d,x ,y;
    public static void main(String args[]){
        InputReader sc = new InputReader(System.in);
        OutputStream outputStream = System.out;
        PrintWriter out = new PrintWriter(outputStream);
        //----------Code Starts Here----
        	int n = sc.nextInt();
        	String a[] = new String[n];
        	for(int i=0;i<n;i++)
        		a[i]=sc.nextLine();
        	Arrays.sort(a,new sortbylength());
        	boolean flag=true;	
        	for(int i=1;i<n;i++)
        	{
        		if(a[i-1].length()<a[i].length())
        		{
        			if(!isSubstring(a[i-1],a[i]))
        			{
        				flag=false;
        				break;
        			}
        		}
        		else
        		{
        			if(!(a[i-1].equals(a[i])))
        			{
        				flag=false;
        				break;
        			}
        		}
        	}
        	if(flag==false)
        		out.println("NO");
        	else
        	{
        		out.println("YES");
        		for(int i=0;i<a.length;i++)
        			out.println(a[i]);
        	}
        //----------The End-------------
        out.close();
    }
    
    public static boolean isSubstring(String s1, String s2)
    {
        int M = s1.length();
        int N = s2.length();
     
        /* A loop to slide pat[] one by one */
        for (int i = 0; i <= N - M; i++) {
            int j;
     
            /* For current index i, check for
            pattern match */
            for (j = 0; j < M; j++)
                if (s2.charAt(i + j) != s1.charAt(j))
                    break;
     
            if (j == M)
                return true;
        }
        return false;
    }
    static int getMaxArea(int hist[], int n) 
    {
        // Create an empty stack. The stack holds indexes of hist[] array
        // The bars stored in stack are always in increasing order of their
        // heights.
        Stack<Integer> s = new Stack<>();
         
        int max_area = 0; // Initialize max area
        int tp;  // To store top of stack
        int area_with_top; // To store area with top bar as the smallest bar
      
        // Run through all bars of given histogram
        int i = 0;
        while (i < n)
        {
            // If this bar is higher than the bar on top stack, push it to stack
            if (s.empty() || hist[s.peek()] <= hist[i])
                s.push(i++);
      
            // If this bar is lower than top of stack, then calculate area of rectangle 
            // with stack top as the smallest (or minimum height) bar. 'i' is 
            // 'right index' for the top and element before top in stack is 'left index'
            else
            {
                tp = s.peek();  // store the top index
                s.pop();  // pop the top
      
                // Calculate the area with hist[tp] stack as smallest bar
                area_with_top = hist[tp] * (s.empty() ? i : i - s.peek() - 1);
                System.out.println(area_with_top);
                // update max area, if needed
                if (max_area < area_with_top)
                    max_area = area_with_top;
            }
        }
      
        // Now pop the remaining bars from stack and calculate area with every
        // popped bar as the smallest bar
        while (s.empty() == false)
        {
            tp = s.peek();
            s.pop();
            area_with_top = hist[tp] * (s.empty() ? i : i - s.peek() - 1);
            System.out.println(area_with_top);
            if (max_area < area_with_top)
                max_area = area_with_top;
        }
      
        return max_area;
 
    }
    private static void reverse(Stack<Integer> s)
    {
    	if(s.isEmpty())
    		return;
    	int top = s.pop();
    	reverse(s);
    	insertbottom(s,top);
    }
    private static void insertbottom(Stack<Integer> s,int t)
    {
    	if(s.isEmpty())
    		s.push(t);
    	else
    	{
    		int top = s.pop();
    		insertbottom(s,t);
    		s.push(top);
    	}
    }
    private static void swap(int[] a , int x,int y) 
    {
    	int temp = a[x];
    	a[x]=a[y];
    	a[y]=temp;
	}
	static int[] spf(int n)
    {
        int spf[] = new int[n+1];
        Arrays.fill(spf,0);
        spf[1] = 1;
     
        for (int i = 2; i <= n; i++)
        {
            if (spf[i] == 0)
            {
                spf[i] = i;
                for (int j = 2*i; j <= n; j += i)
                    if (spf[j] == 0)
                       spf[j] = i;
               
            } 
        }
        return spf;
    }
    private static boolean isPrime(long temp) {
        if(temp==0 || temp==1)
            return false;
        for(long i=2;i<Math.sqrt(temp);i++)
        {
            if(temp%i==0)
                return false;
        }
        return true;
    }
    static long modInverse(long A, long M)
    {
        extendedEuclid(A,M);
        return (x%M+M)%M;    //x may be negative
    }
    static void extendedEuclid(long A, long B) {
       
        if(B == 0) {
            d = A;
            x = 1;
            y = 0;
        }
        else {
            extendedEuclid(B, A%B);
            long temp = x;
            x = y;
            y = temp - (A/B)*y;
        }
    }
   
    static void topologicalSortUtil(int v, boolean visited[],Stack stack,ArrayList<Integer>[] adj)
        {
            // Mark the current node as visited.
                visited[v] = true;
                Integer i;
                for(i=0;i<adj[v].size();i++)
                {
                        int temp = adj[v].get(i);
                        if (!visited[temp])
                            topologicalSortUtil(temp, visited, stack,adj);
                }

                stack.push(new Integer(v));
        }

static void topologicalSort(int top[], int V,ArrayList<Integer>[] adj)
{
Stack stack = new Stack();


boolean visited[] = new boolean[V+1];
for (int i = 0; i <=V; i++)
visited[i] = false;


for (int i = 1; i <=V; i++)
if (visited[i] == false)
topologicalSortUtil(i, visited, stack,adj);

int count=0;
while (stack.empty()==false)
{
    top[count]=(int) stack.pop();
    count++;
}
}
       
        public int find(int parent[],int x)
        {
            if(parent[x]==-1)
                return x;
            return find(parent,parent[x]);
        }
       
        public void union(int parent[],int x,int y)
        {
            int xset = find(parent,x);
            int yset = find(parent,y);
            parent[xset] = yset;
        }
   
   
    private static String  xor(String string, String string2) {
         String temp = "";
         for(int i=0;i<string.length();i++)
         {
             if((string.charAt(i)=='1' && string2.charAt(i)=='1') || (string2.charAt(i)=='0' && string2.charAt(i)=='0'))
                     temp+="0";
             else
                 temp+="1";   
         }
         return temp;
    }

    private static int count_ones(String temp) {
        // TODO Auto-generated method stub
         int count=0;
         for(int i=0;i<temp.length();i++)
                if(temp.charAt(i)=='1')
                    count++;
        return count;
    }

    static int power(int x,int n)
        {
            if(n==0)
                return 1;
            else if(n%2 == 0)        //n is even
                return power(x*x,n/2);
            else                             //n is odd
                return x*power(x*x,(n-1)/2);
        }
    static long ce(long x)
    {
        if(x%2!=0)
            return x/2+1;
        return x/2;
    }
    static boolean isSubSequence(String str1, String str2, int m, int n)
    {
       int j = 0;
       for (int i=0; i<n&&j<m; i++)
           if (str1.charAt(j) == str2.charAt(i))
             j++;
     
       return (j==m);
    }
   
    static long sort(int a[]) {
        int n = a.length;
        int b[] = new int[n];
        return mergeSort(a, b, 0, n - 1);
    }

    static long mergeSort(int a[], int b[], long left, long right) {
        long c = 0;
        if (left < right) {
            long mid = left + (right - left) / 2;
            c = mergeSort(a, b, left, mid);
            c += mergeSort(a, b, mid + 1, right);
            c += merge(a, b, left, mid + 1, right);
        }
        return c;
    }

    static long merge(int a[], int b[], long left, long mid, long right) {
        long c = 0;
        int i = (int) left;
        int j = (int) mid;
        int k = (int) left;
        while (i <= (int) mid - 1 && j <= (int) right) {
            if (a[i] <= a[j]) {
                b[k++] = a[i++];
            } else {
                b[k++] = a[j++];
                c += mid - i;
            }
        }
        while (i <= (int) mid - 1)
            b[k++] = a[i++];
        while (j <= (int) right)
            b[k++] = a[j++];
        for (i = (int) left; i <= (int) right; i++)
            a[i] = b[i];
        return c;
    }
   
       
    static long fibo(long l) {
        if (l < 0) {
            throw new IllegalArgumentException("The fibo value cannot be negative");
        }

        if (l <= 1) return l;

        long[][] result = {{1, 0}, {0, 1}}; // identity matrix.
        long[][] fiboM = {{1, 1}, {1, 0}};

        while (l > 0) {
            if (l%2 == 1) {
                multMatrix(result, fiboM);
            }
            l = l / 2;
            multMatrix(fiboM, fiboM);
        }

        return result[1][0];
    }

    private static void multMatrix(long[][] result, long[][] fiboM) {
        long a = (result[0][0]%mod * fiboM[0][0]%mod)%mod +  (result[0][1]%mod * fiboM[1][0]%mod)%mod;
        long b = (result[0][0]%mod * fiboM[0][1]%mod)%mod + ( result[0][1]%mod * fiboM[1][1]%mod)%mod;
        long c = (result[1][0]%mod * fiboM[0][0]%mod)%mod + ( result[1][1]%mod * fiboM[0][1]%mod)%mod;
        long d = (result[1][0]%mod * fiboM[0][1]%mod)%mod +  (result[1][1]%mod * fiboM[1][1]%mod)%mod;

        result[0][0] = a;
        result[0][1] = b;
        result[1][0] = c;
        result[1][1] = d;
    }
   
   
    static int[] sieve(int n)
    {
        int prime[] = new int[n+1];
        for(int i=0;i<n;i++)
            prime[i] = 1;
        prime[0]=0;
        prime[1]=0;
        for(int p = 2; p*p <=n; p++)
        {
            // If prime[p] is not changed, then it is a prime
            if(prime[p] == 1)
            {
                // Update all multiples of p
                for(int i = p*2; i <= n; i += p)
                    prime[i] = 0;
            }
       
        }
        return prime;
    }
   
    static boolean isPal(String s)
    {
        for(int i=0, j=s.length()-1;i<=j;i++,j--)
        {
            s=s.toLowerCase();
            if(s.charAt(i)!=s.charAt(j)) return false;
        }
        return true;
    }
    public static String rev(String s)
    {
        StringBuilder sb=new StringBuilder(s);
        sb.reverse();
        return sb.toString();
    }
       
    static long lcm(long a, long b)
    {
        return a * (b / gcd(a, b));
    }
   
    static long gcd(long a, long b)
    {
        while (b > 0)
        {
            long temp = b;
            b = a % b; // % is remainder
            a = temp;
        }
        return a;
    }
    static long modulo(long a,long b,long c) {
        long x=1;
        long y=a;
        while(b > 0){
            if(b%2 == 1){
                x=(x*y)%c;
            }
            y = (y*y)%c; // squaring the base
            b /= 2;
        }
        return  x%c;
    }
    public static void debug(Object... o) {
        System.out.println(Arrays.deepToString(o));
    }
    static class Pair implements Comparable<Pair> {
        int a, b;

        Pair(int a, int b) {
            this.a = a;
            this.b = b;
        }

        public int compareTo(Pair o) {
            // TODO Auto-generated method stub
            return Integer.compare(this.b,o.b);
            //return 0;
        }

        public boolean equals(Object o) {
            if (o instanceof Pair) {
                Pair p = (Pair) o;
                return p.a == a && p.b == b;
            }
            return false;
        }

        public int hashCode() {
            return new Integer(a).hashCode() * 31 + new Integer(b).hashCode();
        }

        public String toString() {
            return a + " " + b;
        }
    }
    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream inputstream) {
            reader = new BufferedReader(new InputStreamReader(inputstream));
            tokenizer = null;
        }

        public String nextLine(){
            String fullLine=null;
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    fullLine=reader.readLine();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                return fullLine;
            }
            return fullLine;
        }
        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }
        public long nextLong() {
            return Long.parseLong(next());
        }
        public int nextInt() {
            return Integer.parseInt(next());
        }
    }
}
class Graph
{
    int V;
    int E;
    Edge edge[];
    class Edge
    {
        int src,dest;
    }
    public Graph(int V,int E)
    {
        this.V=V;
        this.E=E;
        edge = new Edge[E];
        for(int i=0;i<E;i++)
            edge[i]=new Edge();
    }
}

class SegmentTree
{
    int st[]; // The array that stores segment tree nodes
 
    /* Constructor to construct segment tree from given array. This
       constructor  allocates memory for segment tree and calls
       constructSTUtil() to  fill the allocated memory */
    SegmentTree(int arr[], int n)
    {
        // Allocate memory for segment tree
        //Height of segment tree
        int x = (int) (Math.ceil(Math.log(n) / Math.log(2)));
 
        //Maximum size of segment tree
        int max_size = 2 * (int) Math.pow(2, x) - 1;
 
        st = new int[max_size]; // Memory allocation
 
        constructSTUtil(arr, 0, n - 1, 0);
    }
 
    // A utility function to get the middle index from corner indexes.
    int getMid(int s, int e) {
        return s + (e - s) / 2;
    }
 
    /*  A recursive function to get the sum of values in given range
        of the array.  The following are parameters for this function.
 
      st    --> Pointer to segment tree
      si    --> Index of current node in the segment tree. Initially
                0 is passed as root is always at index 0
      ss & se  --> Starting and ending indexes of the segment represented
                    by current node, i.e., st[si]
      qs & qe  --> Starting and ending indexes of query range */
    int getSumUtil(int ss, int se, int qs, int qe, int si)
    {
        // If segment of this node is a part of given range, then return
        // the sum of the segment
     //   if (qs <= ss && qe >= se)
       //     return st[si];
        if(qs==qe)
        // If segment of this node is outside the given range
        if (se < qs || ss > qe)
            return 0;
 
        // If a part of this segment overlaps with the given range
        int mid = getMid(ss, se);
        return getSumUtil(ss, mid, qs, qe, 2 * si + 1) +
                getSumUtil(mid + 1, se, qs, qe, 2 * si + 2);
    }
 
    /* A recursive function to update the nodes which have the given
       index in their range. The following are parameters
        st, si, ss and se are same as getSumUtil()
        i    --> index of the element to be updated. This index is in
                 input array.
       diff --> Value to be added to all nodes which have i in range */
    void updateValueUtil(int ss, int se, int i, int diff, int si)
    {
        // Base Case: If the input index lies outside the range of
        // this segment
        if (i < ss || i > se)
            return;
 
        // If the input index is in range of this node, then update the
        // value of the node and its children
        st[si] = st[si] + diff;
        if (se != ss) {
            int mid = getMid(ss, se);
            updateValueUtil(ss, mid, i, diff, 2 * si + 1);
            updateValueUtil(mid + 1, se, i, diff, 2 * si + 2);
        }
    }
 
    // The function to update a value in input array and segment tree.
   // It uses updateValueUtil() to update the value in segment tree
    void updateValue(int arr[], int n, int i, int new_val)
    {
        // Check for erroneous input index
        if (i < 0 || i > n - 1) {
            System.out.println("Invalid Input");
            return;
        }
 
        // Get the difference between new value and old value
        int diff = new_val - arr[i];
 
        // Update the value in array
        arr[i] = new_val;
 
        // Update the values of nodes in segment tree
        updateValueUtil(0, n - 1, i, diff, 0);
    }
 
    // Return sum of elements in range from index qs (quey start) to
   // qe (query end).  It mainly uses getSumUtil()
    int getSum(int n, int qs, int qe)
    {
        // Check for erroneous input values
        if (qs < 0 || qe > n - 1 || qs > qe) {
            System.out.println("Invalid Input");
            return -1;
        }
        return getSumUtil(0, n - 1, qs, qe, 0);
    }
 
    // A recursive function that constructs Segment Tree for array[ss..se].
    // si is index of current node in segment tree st
    int constructSTUtil(int arr[], int ss, int se, int si)
    {
        // If there is one element in array, store it in current node of
        // segment tree and return
        if (ss == se) {
            st[si] = arr[ss];
            return arr[ss];
        }
 
        // If there are more than one elements, then recur for left and
        // right subtrees and store the sum of values in this node
        int mid = getMid(ss, se);
        st[si] = constructSTUtil(arr, ss, mid, si * 2 + 1) +
                 constructSTUtil(arr, mid + 1, se, si * 2 + 2);
        return st[si];
    }
}


class sortbylength implements Comparator<String>
{
	@Override
	public int compare(String o1, String o2) {
		if(o1.length()<o2.length())
			return -1;
		else if(o1.length()>o2.length())
			return +1;
		return 0;
	}
	
}