// TPuzzle.cc
// TF solution to A Puzzling Problem
// ECNA 2007

#include <iostream>
using namespace std;

const int MAX=102;

struct occupied {
  int TheWord;
  occupied *next;
};

char Board[MAX][MAX];
int Graph[MAX][MAX];
occupied *Overlaps[MAX][MAX];

int rows, cols, words;
int visited[MAX];

//*******************************************
void PrintStuff(){
/*
  cout<<"   *** Board *** "<<endl;
  for(int i=0;i<rows;i++){
   for(int j=0;j<cols;j++)
    cout<<Board[i][j];
    cout<<endl;
  }
*/

  cout<<"  *** Graph ***"<<endl;
  for(int i=0;i<words;i++){
   for(int j=0;j<words;j++) 
    cout<<Graph[i][j];
    cout<<endl;
   }
}

void PrintLinks(){
 occupied *ptr;

 for(int i=0;i<rows; i++)
  for(int j=0;j<cols;j++){
    cout<<i<<' '<<j<<':';
    ptr=Overlaps[i][j];
    while(ptr!=NULL){
      cout<<ptr->TheWord;
      ptr = ptr->next;
    }
   cout<<endl;
  }
}

//*******************************************
void Init(){
  for(int i=0;i<rows;i++)
   for(int j=0;j<cols;j++)
    Overlaps[i][j] = NULL;

  //adjacency matrix
  for(int i=0;i<words;i++)
   for(int j=0;j<words;j++)
    Graph[i][j]=0;
   
}

//*******************************************
void GetBoard(){
  for(int i=0;i<rows;i++)
   for(int j=0;j<cols;j++)
    cin>>Board[i][j];
}

//*******************************************
//dispose of all nodes
void CleanUp(){
  occupied *ptr, *ptr2;

  for(int i=0;i<rows;i++)
   for(int j=0;j<cols;j++){
    ptr=Overlaps[i][j];

/*
    while(ptr != NULL){
     ptr2 = ptr->next;
     delete(ptr);
     ptr = ptr2;
    }
*/
   }
}

//*******************************************
//directions: 'A'= NE, 'B'=SE, 'C'=SW, 'D'=NW
bool Found(char w[MAX], int r, int c, char dir){
 int n = strlen(w); 
 
 if(dir=='E')
  for(int i=0; i<n; i++)
   {if(Board[r][c+i] != w[i]) return false;}
 else if(dir=='W')
  for(int i=0; i<n; i++)
   {if(Board[r][c-i] != w[i]) return false;}
 else if(dir=='S')
  for(int i=0; i<n; i++)
   {if(Board[r+i][c] != w[i]) return false;}
 else if(dir=='N')
  for(int i=0; i<n; i++)
   {if(Board[r-i][c] != w[i]) return false;}
 if(dir=='A')
  for(int i=0; i<n; i++)
   {if(Board[r-i][c+i] != w[i]) return false;}
 else if(dir=='B')
  for(int i=0; i<n; i++)
   {if(Board[r+i][c+i] != w[i]) return false;}
 else if(dir=='C')
  for(int i=0; i<n; i++)
   {if(Board[r+i][c-i] != w[i]) return false;}
 else if(dir=='D')
  for(int i=0; i<n; i++)
   {if(Board[r-i][c-i] != w[i]) return false;}

//cout<<"found "<<w<<" at "<< r<<','<<c<<" in dir "<<dir<<endl;
 return true;
}

//*******************************************
//update Overlap and Graph
void Mark(int n, int r, int c, char dir, int wordNo){
  int w;

//if(n==12) 

 if(dir=='E')
  for(int i=0; i<n; i++){
   occupied * node=new(occupied), *ptr;
   node->TheWord=wordNo;
   ptr=Overlaps[r][c+i];
   while(ptr!=NULL){      //make additions to GRAPH[][]
    w = ptr->TheWord;
    Graph[wordNo][w] = Graph[w][wordNo] = 1;
    ptr = ptr->next;
   }
   node->next = Overlaps[r][c+i];
   Overlaps[r][c+i] = node;
  }
 else if(dir=='W')
  for(int i=0; i<n; i++){
   occupied * node=new(occupied), *ptr;
   node->TheWord=wordNo;
   ptr=Overlaps[r][c-i];
   while(ptr!=NULL){      //make additions to GRAPH[][]
    w = ptr->TheWord;
    Graph[wordNo][w] = Graph[w][wordNo] = 1;
    ptr = ptr->next;
   }
   node->next = Overlaps[r][c-i];
   Overlaps[r][c-i] = node;
  }
 else if(dir=='S')
  for(int i=0; i<n; i++){
   occupied * node=new(occupied), *ptr;
   node->TheWord=wordNo;
   ptr=Overlaps[r+i][c];
   while(ptr!=NULL){      //make additions to GRAPH[][]
    w = ptr->TheWord;
    Graph[wordNo][w] = Graph[w][wordNo] = 1;
    ptr = ptr->next;
   }
   node->next = Overlaps[r+i][c];
   Overlaps[r+i][c] = node;
   }
 else if(dir=='N')
  for(int i=0; i<n; i++){
   occupied * node=new(occupied), *ptr;
   node->TheWord=wordNo;
   ptr=Overlaps[r-i][c];
   while(ptr!=NULL){      //make additions to GRAPH[][]
    w = ptr->TheWord;
    Graph[wordNo][w] = Graph[w][wordNo] = 1;
    ptr = ptr->next;
   }
   node->next = Overlaps[r-i][c];
   Overlaps[r-i][c] = node;
   }
 else if(dir=='A')       //NE
  for(int i=0; i<n; i++){
   occupied * node=new(occupied), *ptr;
   node->TheWord=wordNo;
   ptr=Overlaps[r-i][c+i];
   while(ptr!=NULL){      //make additions to GRAPH[][]
    w = ptr->TheWord;
    Graph[wordNo][w] = Graph[w][wordNo] = 1;
    ptr = ptr->next;
   }
   node->next = Overlaps[r-i][c+i];
   Overlaps[r-i][c+i] = node;
  }
 else if(dir=='B')     //SE
  for(int i=0; i<n; i++){
   occupied * node=new(occupied), *ptr;
   node->TheWord=wordNo;
   ptr=Overlaps[r+i][c+i];
   while(ptr!=NULL){      //make additions to GRAPH[][]
    w = ptr->TheWord;
    Graph[wordNo][w] = Graph[w][wordNo] = 1;
    ptr = ptr->next;
   }
   node->next = Overlaps[r+i][c+i];
   Overlaps[r+i][c+i] = node;
  }
 else if(dir=='C')      //SW
  for(int i=0; i<n; i++){
   occupied * node=new(occupied), *ptr;
   node->TheWord=wordNo;
   ptr=Overlaps[r+i][c-i];
   while(ptr!=NULL){      //make additions to GRAPH[][]
    w = ptr->TheWord;
    Graph[wordNo][w] = Graph[w][wordNo] = 1;
    ptr = ptr->next;
   }
   node->next = Overlaps[r+i][c-i];
   Overlaps[r+i][c-i] = node;
  }
 else if(dir=='D')
  for(int i=0; i<n; i++){
   occupied * node=new(occupied), *ptr;
   node->TheWord=wordNo;
   ptr=Overlaps[r-i][c-i];
   while(ptr!=NULL){      //make additions to GRAPH[][]
    w = ptr->TheWord;
    Graph[wordNo][w] = Graph[w][wordNo] = 1;
    ptr = ptr->next;
   }
   node->next = Overlaps[r-i][c-i];
   Overlaps[r-i][c-i] = node;
  }
//PrintStuff();
//PrintLinks(); cout<<endl;
}

//*******************************************
void FindWord(char w[MAX], int k){
 int n;

 //make all upper
 for(int i=0;i<strlen(w);i++)
  w[i] = toupper(w[i]);

 n  = strlen(w);

 for(int i=0;i<rows;i++)
  for(int j=0;j<cols;j++){
   //check right
   if(n <= cols-j && Board[i][j]==w[0]){
    if(Found(w,i,j,'E')){
     Mark(n,i,j,'E',k);
     return;
    }
   }
   //checkleft 
   if(n <= j+1 && Board[i][j]==w[0]){
    if(Found(w,i,j,'W')){
     Mark(n,i,j,'W',k);
     return;
    }
   }
   //check down
   if(n <= rows-i& Board[i][j]==w[0]){
    if(Found(w,i,j,'S')){
     Mark(n,i,j,'S',k);
     return;
    }
   }
   //check up
   if(n <= i+1 && Board[i][j]==w[0]){
    if(Found(w,i,j,'N')){
     Mark(n,i,j,'N',k);
     return;
    }
   }
   //check NE 
   if(n <= cols-j && n <= i+1 && Board[i][j]==w[0]){
    if(Found(w,i,j,'A')){
     Mark(n,i,j,'A',k);
     return;
    }
   }
   //check SE
   if(n <= cols-j  && n <= rows-i&& Board[i][j]==w[0]){
    if(Found(w,i,j,'B')){
     Mark(n,i,j,'B',k);
     return;
    }
   }
   //check SW
   if(n <= j+1 && n<= rows-i && Board[i][j]==w[0]){
    if(Found(w,i,j,'C')){
     Mark(n,i,j,'C',k);
     return;
    }
   }
   //check NW
   if(n <= i+1 && n <= j+1 && Board[i][j]==w[0]){
    if(Found(w,i,j,'D')){
     Mark(n,i,j,'D',k);
     return;
    }
   }
  }
}

//*******************************************
void BFS(int k){
  if(visited[k]) return;
  visited[k] = 1;

  for(int i=0;i<words;i++)
   if(Graph[k][i] && !visited[i]) BFS(i);

}

//*******************************************
//is graph connected if node n is removed?
//uses BFS
bool IsConnected(int n){

 for(int i=0;i<words;i++) visited[i]=0;
 visited[n]=1;  

 if(n>0) BFS(0);
 else    BFS(1);

 for(int i=0;i<words;i++)
  if(visited[i] == 0) return false;

 return true;
}
 
  
//*******************************************
int main(){
 char w[MAX];
 bool BiCon;

 cin>>rows>>cols>>words;
 
 while(rows>0){
  Init();
  GetBoard();

  for(int i=0;i<words;i++){
   cin>>w;
   FindWord(w,i);
  }

//cout<<"done"<<endl;
//PrintStuff();

//cout<<" seeing is biconnected"<<endl;
  BiCon = true;
  for(int i=0;i<words;i++)
   if(!IsConnected(i)) BiCon = false;

  if(BiCon) cout<<"Yes"<<endl;
  else      cout<<"No"<<endl;

  CleanUp();

  cin>>rows>>cols>>words;
 }

 return 0;
}

