// Arup Guha
// 3/6/2024
// Solution to 2024 COP 3503 Program #5 Part C: Short Codes

import java.util.*;

public class codes3 {

	public static void main(String[] args) {
	
		Scanner stdin = new Scanner(System.in);
		int n = stdin.nextInt();
		int m = stdin.nextInt();
		
		String[] drugs = new String[n];
		for (int i=0; i<n; i++)
			drugs[i] = stdin.next();
		
		// Sort so we know these are in lexicographical order.
		String[] codes = new String[m];
		for (int i=0; i<m; i++)
			codes[i] = stdin.next();
		Arrays.sort(codes);
		
		// links[i] will store the indexes of the codes that it matches with.
		ArrayList<Integer>[] links = getLinks(drugs, codes);
		
		// This will return the first lexicographical map from drugs to codes, if it exists.
		int[] map = getMap(links, m);
		
		// There was no mapping.
		if (map == null)
			System.out.println("no");
		
		// We found a mapping.
		else {
			
			System.out.println("yes");
			
			// This was the first lexicographical mapping.
			for (int i=0; i<map.length; i++)
				System.out.println(codes[map[i]]);
		}
	}
	
	// Returns an array of lists, where list[i] will store the index of each code that drug i 
	// could possibly map to.
	public static ArrayList<Integer>[] getLinks(String[] drugs, String[] codes) {

		// Initialize our list of lists.
		ArrayList<Integer>[] res = new ArrayList[drugs.length];
		for (int i=0; i<res.length; i++)
			res[i] = new ArrayList<Integer>();
		
		// Now add an j iff drug i could match to the code j.
		for (int i=0; i<drugs.length; i++)
			for (int j=0; j<codes.length; j++)
				if (drugs[i].contains(codes[j]))
					res[i].add(j);
					
		// Return this.
		return res;
	}
	
	public static int[] getMap(ArrayList<Integer>[] links, int numDrugs) {
		
		// Store the result here.
		int n = links.length, m = numDrugs;
		int[] res = new int[n];
		boolean[] usedCodes = new boolean[m];
		
		// i is the drug we're matching.
		for (int i=0; i<n; i++) {
			
			boolean foundMatch = false;
			
			// We will try mapping drug i to code x.
			for (Integer x: links[i]) {
				
				// This code is not allowed!
				if (usedCodes[x]) continue;
				
				// Temporarily mark this.
				usedCodes[x] = true;
				
				// This is our flow graph.
				FordFulkerson ff = new FordFulkerson(n+m);
				
				// Links from source to drugs.
				for (int z=i+1; z<n; z++)
					ff.add(n+m,z,1);
				
				// Links from codes to sink.
				for (int z=0; z<m; z++)
					ff.add(n+z,n+m+1,1);
				
				// Set up the rest of the links. j is the drug here.
				for (int j=i+1; j<links.length; j++) {
					
					// y is the code.
					for (Integer y: links[j]) {
						if (usedCodes[y]) continue;
						ff.add(j,n+y,1);
					}
				}
				
				// Run flow.
				int flow = ff.ff();
				
				// There exists a matching with drug i matched to code x, do it!!!
				if (flow == n-i-1) {
					res[i] = x;
					foundMatch = true;
					break;
				}
				
				// Undo this mapping.
				usedCodes[x] = false;
			}
			
			// No match was found for drug i. Stop.
			if (!foundMatch) return null;
		}
		
		// If we get here, we're good.
		return res;
	}
}

/*** Class FF code unedited ***/

class FordFulkerson {

	// Stores graph.
	public int[][] cap;
	public int n;
	public int source;
	public int sink;

	// "Infinite" flow.
	final public static int oo = (int)(1E9);

	// Set up default flow network with size+2 vertices, size is source, size+1 is sink.
	public FordFulkerson(int size) {
		n = size + 2;
		source = n - 2;
		sink = n - 1;
		cap = new int[n][n];
	}

	// Adds an edge from v1 -> v2 with capacity c.
	public void add(int v1, int v2, int c) {
		cap[v1][v2] = c;
	}

	// Wrapper function for Ford-Fulkerson Algorithm
	public int ff() {

		// Set visited array and flow.
		boolean[] visited = new boolean[n];
		int flow = 0;

		// Loop until no augmenting paths found.
		while (true) {

			// Run one DFS.
			Arrays.fill(visited, false);
			int res = dfs(source, visited, oo);

			// Nothing found, get out.
			if (res == 0) break;

			// Add this flow.
			flow += res;
		}

		// Return it.
		return flow;
	}

	// DFS to find augmenting math from v with maxflow at most min.
	public int dfs(int v, boolean[] visited, int min) {

		// got to the sink, this is our flow.
		if (v == sink)  return min;

		// We've been here before - no flow.
		if (visited[v])  return 0;

		// Mark this node and recurse.
		visited[v] = true;
		int flow = 0;

		// Just loop through all possible next nodes.
		for (int i = 0; i < n; i++) {

			// We can augment in this direction.
			if (cap[v][i] > 0)
				flow = dfs(i, visited, Math.min(cap[v][i], min));

			// We got positive flow on this recursive route, return it.
			if (flow > 0) {

				// Subtract it going forward.
				cap[v][i] -= flow;

				// Add it going backwards, so that later, we can flow back through this edge as a backedge.
				cap[i][v] += flow;

				// Return this flow.
				return flow;
			}
		}

		// If we get here there was no flow.
		return 0;
	}
}