#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
// using namespace atcoder;
typedef int64_t lint;
#define rep(i, n) for(int i=0; i<n; i++)
#define repx(i, l, n) for(int i=l; i<n; i++)
#define all(v) v.begin(), v.end()
#define show(x) cout << #x << ": " << x << endl;
#define list(x) cout << #x << ": " << x << "  ";
#define pb push_back
using vi = vector<lint>;
using vvi = vector<vector<lint>>;
template<class T> inline void vin(vector<T>& v) { rep(i, v.size()) cin >> v.at(i); }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T> inline void drop(T x) { cout << x << endl; exit(0); }
template<class T> void vout(vector<T> v) { rep(i, v.size()) { cout << v.at(i) << ' '; } cout << endl; }
constexpr lint LINF = LLONG_MAX/2;

int main() {
	int N, M;
	cin >> N >> M;
	vector<pair<int, string>> V(M);
	string s;
	rep(i, M) {
		cin >> s;
		V[i] = {s.size(), s};
	}
	sort(all(V));
	vector<vector<string>> T(8);
	rep(i, M) {
		T[(V[i].second[0]-'A')].pb(V[i].second);
	}

	int a=0, b=0, c=0, x, y, z;
	vi v(8);
	vector<string> S(20);
	rep(i, M) {
		s = T[b][v[b]];
		if (S[a].size() + s.size() > 20) a++;
		if (a == 20) break;
		if (S[a].size()) S[a] = S[a].substr(0, S[a].size()-1);
		S[a] += s;
		v[b] = (v[b]+1)%T[b].size();
		b = s[s.size()-1]-'A';
	}
	rep(i, 20) {
		rep(j, 20) {
			if (S[i].size() < 20) S[i] += 'A' + rand()%8;
		}
		std::cout << S[i] << '\n';
	}
}

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>

bool contains(const std::string& s, const std::string& v)
{
  return s.find(v) != std::string::npos;
}

std::vector<std::string> erase_contained(std::vector<std::string> ss)
{
  std::sort(ss.begin(), ss.end());
  ss.erase(std::unique(ss.begin(), ss.end()), ss.end());

  std::vector<std::string> result;
  for (auto& e : ss)
  {
    bool contained = false;
    for (auto& f : ss)
    {
      if (e == f) { continue; }
      if (contains(f,e))
      {
        contained = true;
        break;
      }
    }
    if (!contained) { result.push_back(e); }
  }

  return result;
}

std::vector<std::set<std::pair<int, int>>>
connect_info(const std::vector<std::string>& ss, int len)
{
  std::vector<std::set<std::pair<int, int>>> connect(ss.size());
  for (int i = 0; i < ss.size(); i++)
  {
    for (int j = 0; j < ss.size(); j++)
    {
      if (i == j) { continue; }
      for (int n = ss[i].length() - 1; len <= n; n--)
      {
        if (ss[i].substr(ss[i].length() - n) == ss[j].substr(0, n))
        {
          connect[i].insert({ n, j });
          break;
        }
      }
    }
  }
  return connect;
}

std::vector<std::string>
merge(std::vector<std::string> ss, const std::vector<std::set<std::pair<int, int>>>& info, int len)
{
  std::vector<std::string> result;
  for (int i = 0; i < ss.size(); i++)
  {
    if (ss[i].empty()) { continue; }
    if (info[i].empty()) { continue; }
    std::vector<std::pair<int, int>> infos(info[i].begin(), info[i].end());
    std::reverse(infos.begin(), infos.end());
    for (auto& info : infos)
    {
      if (ss[info.second].empty()) { continue; }
      if (info.first < len) { continue; }
      result.push_back(ss[i].substr(0, ss[i].length() - info.first) + ss[info.second]);
      ss[i] = "";
      ss[info.second] = "";
      break;
    }
  }
  for (auto& e : ss)
  {
    if (!e.empty()) { result.push_back(e); }
  }
  return result;
}

//std::vector<std::string> merge_common_part(std::vector<std::string> ss, int len)
//{
//  std::set<std::string> sss(ss.begin(), ss.end());
//  for (int n = 12; len <= n; n--)
//  {
//    for(auto it_l = sss.begin(); it_l !=sss.end  (); it_l++)
//    {
//      if (it_l->length() <= n) { continue; }
//      auto common = it_l->substr(it_l->length()-n);
//      auto it_r = sss.upper_bound(common);
//      if (it_r == sss.end()) { continue; }
//      if (it_l == it_r) { continue; }
//      if (common != it_r->substr(0, common.length())) { continue; }
//
//      int x = 0;
//    }
//  }
//  return {};
//}



int main()
{
  int N, M;
  std::cin >> N >> M;

  std::vector<std::string> ss(M);
  for (auto& e : ss) { std::cin >> e; }
  ss = erase_contained(ss);

  int length = 100000000;
  int level = 5;
  while (true)
  {
    auto cinfo = connect_info(ss, level);
    auto ssm = merge(ss, cinfo, level);
    ss = erase_contained(ssm);
    auto len = 0;
    for (auto& e : ss)
    {
      len += e.length();
    }
    if (length == len)
    {
      if (level == 5) { break; }
      level--;
    }
    length = len;
  }

  std::vector<std::string> ans(N);
  for (auto& s : ss)
  {
    for (int i = 0; i < N; i++)
    {
      if (ans[i].length() + s.length() <= N)
      {
        ans[i] += s;
        break;
      }
    }
  }

  for (auto& e : ans)
  {
    std::cout << e << std::string(20-e.length(), '.') << std::endl;
  }

  return 0;
}
