#include<bits/stdc++.h>
using namespace std;
const int flg[4][2]={{0,-1},{0,1},{1,0},{-1,0}};
int n,m,dp[55][55];
// dp[i][j]:光标在(i,j),最远匹配到s的第几位
int len;
string s;
char ch[55][55];
struct HLC{
int x,y;
int pos; // 当前已经匹配到s的pos位,下一个要匹配s[pos]
int step; // 已经按了多少次按键
};
queue<HLC>q;
// f[i][j][d]:在(i,j)按方向d,跳到的坐标
pair<int,int>f[55][55][4];
void BFS(){
int pos=1;
while(pos<=len && ch[1][1]==s[pos]) pos++;//初始化次数
dp[1][1]=pos;
q.push({1,1,pos,pos-1}); // pos-1是按选择键的次数
while(!q.empty()){
auto now=q.front();
q.pop();
int x=now.x,y=now.y;
int p=now.pos;
int st=now.step;
if(p>len){ // 全部匹配完成
cout<<st<<endl;
return;
}
// 4个方向移动
for(int d=0;d<4;d++){
auto [nx,ny]=f[x][y][d];
if(nx<1||nx>n||ny<1||ny>m) continue;
// 移动这一步:按方向键,按键+1
int np=p;
int nst=st+1;
// 移动到(nx,ny)后,不断按选择,匹配s[np]
while(np<=len && ch[nx][ny]==s[np]){
np++;
nst++;
}
// 如果这个状态更好(匹配到更长),更新入队
if(np>dp[nx][ny]){
dp[nx][ny]=np;
q.push({nx,ny,np,nst});
}
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>ch[i][j];
}
}
//预处理方向跳转 f[i][j][k]
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int k=0;k<4;k++){
int x=i+flg[k][0];
int y=j+flg[k][1];
//沿方向一直走,直到越界j
while(x>=1&&x<=n&&y>=1&&y<=m&&ch[x][y]==ch[i][j]){
x+=flg[k][0];
y+=flg[k][1];
}
f[i][j][k]=make_pair(x,y);
}
}
}
cin>>s;
len=s.size()+1;//目标串长度加末尾换行符
s=" "+s;//加空格,使下标从1开始
s.push_back('*');
BFS();//开始广搜
return 0;
}