#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
#include <tuple>
#include <cstdint>
#include <cstdio>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <cassert>
#include <time.h>

#define rep(i, n) for(int i = 0; i < n; i++)
#define per(i, n) for(int i = n - 1; i >= 0; i--)
using ll = long long;
#define vi vector<int>
#define vvi vector<vi>
#define vl vector<ll>
#define vd vector<double>
#define vvd vector<vd>
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pdi pair<double, int>
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
using namespace std;
constexpr int n = 20;
int m;
vector<string> s;
vector<deque<string>> ss(n + 1);
set<string> cnt;
vvi board(n, vi(n));
int score = 0;

void setset(){
	rep(i, n){
		string t = "";
		rep(j, n) t += board[i][j] + 'A';
		rep(j, n){
			for(int k = 2; (k + j <= n && k <= 12); k++) cnt.insert(t.substr(j, k));
		}
	}
	rep(j, n){
		string t = "";
		rep(i, n) t += board[i][j] + 'A';
		rep(i, n){
			for(int k = 2; (k + i <= n && k <= 12); k++) cnt.insert(t.substr(i, k));
		}
	}
}
int calc_score(){
	cnt.clear();
	setset();
	int v = 0;
	rep(i, m) if(cnt.count(s[i])) v++;
	return v;
}
void random_select(){
	int num = rand() % 2 + 1;
	vector<tuple<int,int,int>> info;
	rep(_, num){
		int i = rand() % n;
		int j = rand() % n;
		int k = rand() % 8;
		info.push_back({i,j,board[i][j]});
		board[i][j] = k;
	}
	int val = calc_score();
	//もとに戻す
	if(score >= val) rep(i, num){
		int a,b,c;
		tie(a, b, c) = info[i];
		board[a][b] = c;
	}
	else score = val;
}
void tekitou_sort(){
	rep(i, n){
		int nokori = n;
		while(true){
			bool found = false;
			for(int j = nokori; j >= 0; j--) if(!ss[j].empty()){
				found = true;
				rep(k, j) board[i][n-nokori+k] = ss[j][0][k] - 'A';
				nokori -= j;
				ss[j].pop_front();
				break;
			}
			if(!found) break;
		}
	}
}
void inputs(){
	cin >> m >> m;
	s.resize(m);
	rep(i, m) cin >> s[i];
}

int main(){
	srand(time(NULL));
	inputs();
	rep(i, m) ss[s[i].size()].push_back(s[i]);

	rep(i, n) rep(j, n) board[i][j] = rand() % 8;
	tekitou_sort();
	score = calc_score();

	rep(i, 100) random_select();

	rep(i, n){
		rep(j, n) printf("%c", board[i][j] + 'A');
		printf("\n");
	}
}
#include <iostream>
using namespace std;

const int INF = 100000000;

int b[10005][102];

bool judge(int k, int n, int *a){
    for(int i = 0; i < k; i++){
        for(int j = 0; j <= n; j++){
            b[i][j] = a[j] / k;
            if(a[j] % k > i) b[i][j]++;
        }
    }
    for(int i = 0; i < k; i++){
        for(int j = 0; j < n; j++){
            if(b[i][j] == b[i][j + 1]) return false;
        }
    }
    return true;
}

int main()
{
    int n;
    cin >> n;
    string s;
    cin >> s;
    int a[102];
    for(int i = 0; i <= n; i++) cin >> a[i];
    int left = 1, right = 10001;
    while(right - left > 1){
        int mid = (right + left) / 2;
        if(judge(mid, n, a)) left = mid;
        else right = mid;
    }
    cout << left << endl;
    judge(left, n, a);
    for(int i = 0; i < left; i++){
        for(int j = 0; j <= n; j++) cout << b[i][j] << " ";
        cout << endl;
    }
}
