#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <functional>
#include <cmath>
#include <climits>
#include <memory.h>

#if !defined(__GNUC__)
#include <hash_set>
#include <hash_map>
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed long int32_t;
typedef unsigned long uint32_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#else // !defined(__GNUC__)
#include <ext/hash_set>
#include <ext/hash_map>
namespace stdext = __gnu_cxx;
#define _CrtDbgBreak()
#endif // !defined(__GNUC__)

#if defined(ONLINE_JUDGE)
#define LOCAL_TEST 0
#else 
#define LOCAL_TEST 1
#endif

#if 1//LOCAL_TEST
#define LOCAL_ASSERT(expr) if (!(expr)) {std::cout << "ASSERT FAILED: '" << #expr << "'" << std::endl; _CrtDbgBreak(); }
#else
#define LOCAL_ASSERT(expr)
#endif

typedef long double double_t;
typedef std::string string8_t;

typedef std::vector<size_t> vector_size_t;
typedef std::vector<uint64_t> vector_uint64_t;
typedef std::vector<int32_t> vector_int32_t;
typedef std::vector<vector_size_t> vector_2d_size_t;
typedef std::vector<string8_t> vector_string8_t;
typedef std::set<size_t> set_size_t;
typedef stdext::hash_set<size_t> hash_set_size_t;
typedef std::multiset<string8_t> multiset_string8_t;

// Auxiliary functions definition
// 
template<typename T> inline T Abs(const T a) { return a < 0 ? -a : a; }
template<typename T> inline T Min(const T a, const T b) {return a < b ? a : b;}
template<typename T> inline T Max(const T a, const T b) {return a > b ? a : b;}
template<typename T> inline void UpdateMin(T& a, const T b) {a = Min(a, b);}
template<typename T> inline void UpdateMax(T& a, const T b) {a = Max(a, b);}

template<typename T> inline void UpdateMaxEx(T& maxVal, T& maxArg, const T currVal, const T currArg)
{
    if (maxVal < currVal)
    {
        maxVal = currVal;
        maxArg = currArg;
    }
}

static const double_t eps = 1.0e-09;
template<typename T> inline bool IsEqual(const T a, const T b) { return Abs(a - b) < eps; }
template<typename T> inline bool IsGreater(const T a, const T b) { return a > b + eps; }
template<typename T> inline bool IsLess(const T a, const T b) { return a + eps < b; }

template<typename T> inline string8_t ToStr(const T& val) { std::ostringstream ostr; ostr << val; return ostr.str(); }
template<typename T> inline bool FromStr(const string8_t& str, T& val) {std::istringstream istr(str); istr >> val; return !!istr; }

#if defined(ONLINE_JUDGE)
template<size_t id> class StopWatch { };
#elif !defined(__GNUC__)
#include <library/lib_stopwatch.h>
#else 
#include "../../library/library/lib_stopwatch.h"
#endif

const size_t MaxPow = 20;

size_t GetLength(const vector_size_t& lengths, const size_t iBegin, const size_t iEnd)
{
    size_t ans = 0;
    for (size_t i = iBegin; i < iEnd; i++)
    {
        if (i != iBegin)
            ans += 1;
        ans += lengths[i];
    }
    return ans;
}

void PrepareFirstLine(const size_t n, const size_t c, const vector_size_t& lengths, vector_size_t& firstLine, size_t& maxCount, size_t& maxStart)
{
    size_t iEnd = 0;
    size_t currLength = 0;
    for (size_t iBegin = 0; iBegin < n; iBegin++)
    {
        if (lengths[iBegin] > c)
        {
            currLength = 0;
            iEnd = iBegin + 1;
            continue;
        }

        if (lengths[iBegin] == c)
        {
            currLength = 0;
            firstLine[iBegin] = 1;
            UpdateMaxEx(maxCount, maxStart, size_t(1), iBegin);
            iEnd = iBegin + 1;
            continue;
        }

        LOCAL_ASSERT(iEnd >= iBegin);
        if (iBegin == iEnd)
            LOCAL_ASSERT(currLength == 0);

        while (iEnd < n)
        {
            size_t newLength = currLength + lengths[iEnd];
            newLength += currLength == 0 ? 0 : 1;
            if (newLength > c)
                break;
            currLength = newLength;
            iEnd++;
        }

        const size_t currCount = iEnd - iBegin;
        firstLine[iBegin] = currCount;
        currLength -= lengths[iBegin] + (currCount == 1 ? 0 : 1);
        LOCAL_ASSERT(iBegin < iEnd);
    }

#if 1// LOCAL_TEST
    for (size_t i = 0; i < n; i++)
    {
        const size_t len = GetLength(lengths, i, i + firstLine[i]);
        const size_t nextLen = GetLength(lengths, i, i + firstLine[i] + 1);
        LOCAL_ASSERT(len <= c);
        LOCAL_ASSERT(nextLen > c);
    }
#endif
}

void PrepareOtherLines(const size_t n, const size_t /*c*/, const vector_size_t& /*lengths*/, vector_2d_size_t& maxCounts, size_t& maxCount, size_t& maxStart)
{
    for (size_t pw = 1; pw < MaxPow; pw++)
    {
        vector_size_t& prevLine = maxCounts[pw - 1];
        vector_size_t& currLine = maxCounts[pw];

        for (size_t iBegin = 0; iBegin < n; iBegin++)
        {
            const size_t prevAns = prevLine[iBegin];
            currLine[iBegin] = prevAns;
            currLine[iBegin] += prevLine[iBegin + prevAns];

            const size_t currentCount = currLine[iBegin];
            UpdateMaxEx(maxCount, maxStart, currentCount, iBegin);
        }
    }   
}

string8_t Join(const vector_string8_t& words, const size_t iBegin, const size_t iEnd)
{
    string8_t ans;
    for (size_t i = iBegin; i < iEnd; i++)
    {
        if (i != iBegin)
            ans += ' ';
        ans += words[i];
    }
    return ans;
}

bool Solve(std::istream& ist, std::ostream& ost, const bool multipleTestMode)
{
    StopWatch<1> sw;

    // 
    size_t n, r, c;
    ist >> n >> r >> c;

    if (multipleTestMode && !ist)
        return false;

    // 
    vector_string8_t words(n);
    vector_size_t lengths(n + 1);
    for (size_t i = 0; i < n; i++)
    {
        ist >> words[i];
        lengths[i] = words[i].length();
    }
    lengths[n] = c + 1;

    size_t maxCount = 0;
    size_t maxStart = 0;
    vector_2d_size_t maxCounts(MaxPow, vector_size_t(n + 1));

    vector_size_t& firstLine = maxCounts[0];
    PrepareFirstLine(n, c, lengths, firstLine, maxCount, maxStart);
    PrepareOtherLines(n, c, lengths, maxCounts, maxCount, maxStart);

#if LOCAL_TEST
    ost << maxCount << ' ' << maxStart << std::endl;
#endif

    size_t idx = maxStart;
    for (size_t i = 0; i < r; i++)
    {
        const size_t nextIdx = idx + firstLine[idx];
        if (idx == nextIdx)
            break;
        const string8_t& line = Join(words, idx, nextIdx);
        ost << line << std::endl;
        idx = nextIdx;
    }

    return multipleTestMode;
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    std::istream& ist = std::cin;
    std::ostream& ost = std::cout;
#if defined(ONLINE_JUDGE)
    Solve(ist, ost, false);
#else
    while(Solve(ist, ost, true)) {};
#endif
}
