#pragma GCC optimize("Ofast") 
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define sz(a) (int)(a.size())
#define all(a) a.begin(),a.end()
#define lb lower_bound
#define ub upper_bound
#define owo ios_base::sync_with_stdio(0);cin.tie(0);
#define MOD (ll)(1e9+7)
#define INF (ll)(1e18)
#define debug(...) fprintf(stderr, __VA_ARGS__),fflush(stderr)
#define time__(d) for(long blockTime = 0; (blockTime == 0 ? (blockTime=clock()) != 0 : false);\
debug("%s time : %.4fs\n", d, (double)(clock() - blockTime) / CLOCKS_PER_SEC))
typedef long long int ll;
typedef long double ld;
typedef pair<ll,ll> PII;
typedef pair<int,int> pii;
typedef vector<vector<int>> vii;
typedef vector<vector<ll>> VII;
ll gcd(ll a,ll b){if(!b)return a;else return gcd(b,a%b);}
VII dist(600,vector<ll>(600,INF));
int main()
{
	owo
	int r,c;
	cin>>r>>c;
	VII a(r,vector<ll>(c)),b(r,vector<ll>(c));
	for(int i=0;i<r;i++)
		for(int j=0;j<c-1;j++)cin>>a[i][j];
		
	for(int i=0;i<r-1;i++)
		for(int j=0;j<c;j++)cin>>b[i][j];	
		
	dist[0][0] = 0;
	priority_queue<pair<ll,pii>,vector<pair<ll,pii>>,greater<pair<ll,pii>>>pq;
	pq.push({0,{0,0}});
	while(!pq.empty()){
		ll d = pq.top().fi;
		pii v = pq.top().se;
		pq.pop();
		if(d != dist[v.fi][v.se])continue;
		int rn = v.fi;
		int cn = v.se;
		if(cn < c-1 && d+a[rn][cn] < dist[rn][cn+1]){
			dist[rn][cn+1] = d+a[rn][cn];
			pq.push({dist[rn][cn+1],{rn,cn+1}});
		}
		if(cn && d+a[rn][cn-1] < dist[rn][cn-1]){
			dist[rn][cn-1] = d+a[rn][cn-1];
			pq.push({dist[rn][cn-1],{rn,cn-1}});			
		}
		if(rn < r-1 && d+b[rn][cn] < dist[rn+1][cn]){
			dist[rn+1][cn] = d+b[rn][cn];
			pq.push({dist[rn+1][cn],{rn+1,cn}});
		}
		for(int i=rn-1;i>=0;i--){
			if(dist[i][cn] > d+rn-i+1){
				dist[i][cn] = d+rn-i+1;
				pq.push({dist[i][cn],{i,cn}});
				
			}
		}
	}
	cout<<dist[r-1][c-1];
}

#include <bits/stdc++.h>
using namespace std;

int main() {
  int M;
  cin >> M >> M;
  vector<string> s(M);
  map<string, int> m;
  set<string> S;
  vector<vector<char>> a(20, vector<char>(20, 'A'));
  deque<tuple<int, int, string>> t;
  for (int i = 0; i < M; i++) {
    cin >> s.at(i);
    if (m.count(s.at(i))) {
      m.at(s.at(i))++;
    }
    else {
      m[s.at(i)] = 1;
    }
  }
  for (int i = 0; i < M; i++) {
    if (!(S.count(s.at(i)))) {
      S.insert(s.at(i));
      t.push_back(make_tuple(m.at(s.at(i)), (int)s.at(i).size(), s.at(i)));
    }
  }
  sort(t.begin(), t.end());
  for (int i = 0; i < 20; i++) {
    M = 0;
    for (int j = 0; j < 10; j++) {
      if (M + get<1>(t.front()) > 19) {
        break;
      }
      for (int k = 0; k < get<1>(t.front()); k++) {
        a.at(i).at(M + k) = get<2>(t.front()).at(k);
      }
      M += get<1>(t.front());
      t.pop_front();
    }
  }
  for (int i = 0; i < 20; i++) {
    for (int j = 0; j < 20; j++) {
      cout << a.at(i).at(j);
      if (j > 18) {
        cout << endl;
      }
    }
  }
}
