Problem:
H: 文字列の連結
問題
s_0,s_1,...,s_{N-1}
と名前の付いた長さ
L
の文字列が
N
種類、それぞれ
10^{10}
個ある。また、空の文字列と空の数列を持っている。
初期状態で空である文字列、数列に対して①か②のルールのどちらか一方のみに従った操作を行い、長さ
K
の文字列と、空でない数列を作る。ただし、どちらのルールを選んだ場合でも、長さ
K
の文字列を作ったときに出来上がる数列が辞書順最小となるように操作を行う。
ルール① 今持っている数列が
str
、数列が
arr
であるとき、以下の操作を行うことができる。
N
種類の文字列の中から文字列を1つ選ぶ。選んだ文字列を
s_{idx}
とする。
L
未満かつ
|str|
以下の非負整数
c
を選ぶ。ただし、
str
の末尾
c
文字と、
s_{idx}
の先頭
c
文字が等しくなければならない。
str
の末尾に
s_{idx}
の末尾
L-c
文字を加え、
arr
の末尾に
idx
を追加する。
ルール② 今持っている数列が
str
、数列が
arr
であるとき、以下の操作を行うことができる。
N
種類の文字列の中から文字列を1つ選ぶ。選んだ文字列を
s_{idx}
とする。
L
未満かつ
|str|
以下の非負整数
c
は次の条件を満たす。
str
の末尾
c
文字と、
s_{idx}
の先頭
c
文字が一致するもののうち、
最大
のものである。
str
の末尾に
s_{idx}
の末尾
L-c
文字を加え、
arr
の末尾に
idx
を追加する。
ルール①かルール②を選んで、選んだ一方のみに従った操作を行い、出来上がった数列の要素数と各要素を出力せよ。
ただし、すべてのテストケースでどちらのルールを選んでも長さ
K
の文字列を作れることが保証されている。
要素数
A
の数列
a=\{a_0,a_1,...,a_{A-1}\}
が要素数
B
の数列
b=\{b_0,b_1,...,b_{B-1}\}
より辞書順で小さいとは、二つの数列が異なり、以下の条件のうちどちらかを満たすことである。
a_i\lt b_i
かつ、任意の
j\lt i
について
a_j = b_j
であるような
0 \leq i \lt
min
(A,B)
が存在する。
任意の
0 \leq i \lt
min
(A,B)
について
a_i=b_i
であり、かつ
A\lt B
である。
入力形式
L
N
K
s_0
s_1
...
s_{N-1}
制約
2\leq N
N\times K\leq 10^5
1\leq L\leq K
与えられる文字列はすべて異なる。
与えられる文字列は英小文字で構成される。
どちらのルールを選んでも長さ
K
の文字列を作ることができる。
出力形式
1行目には作った数列のサイズを出力せよ。
2行目には作った数列の各要素を空白区切りで出力せよ。
入力例1
3 3 6
abc
def
ghi
出力例1
2
0 0
ルール①を選んだ場合、文字列
abc
を2回選び、数列
\{0,0\}
を作ると辞書順最小になります。
入力例2
3 2 5
abd
dcb
出力例2
2
0 1

Submitted solutions:

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

vector<int> Zalgo(string s){
    int n=s.size();
    vector<int> a(n,0);
    int from=-1,last=-1;
    for(int i=1;i<n;i++){
        int &same=a[i];
        if(from!=-1){
            same=min(a[i-from],last-i);
            same=max(0,same);
        }
        while(i+same<n&&s[same]==s[i+same]){
            same++;
        }
        if(last<i+same){
            last=i+same;
            from=i;
        }
    }
    a[0]=n;
    return a;
}

vector<int> slv1(int n, int L, vector<string> s) {
    vector<int> res;
    vector<pair<string,int>> str; str.reserve(n*s[0].size());
    vector<vector<vector<int>>> kouho(n, vector<vector<int>>(n));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < s[i].size()-1; ++j) {
            str.push_back({s[i].substr(0, j+1), i+1});
            str.push_back({s[i].substr(j+1), -(i+1)});
            kouho[i][j].push_back(s[0].size());
        }
    }
    sort(str.begin(), str.end());

    for (int i = 0; i < str.size(); ) {
        vector<int> in,out;
        int j = i;
        while (j < str.size() and str[i].first == str[j].first) {
            int pos = abs(str[j].second)-1;
            if (str[j].second > 0) out.push_back(pos);
            else in.push_back(pos);
            j += 1;
        }
        for (int k : in) {
            for (int l : out) {
                kouho[k][l].push_back(s[0].size()-str[i].first.size());
            }
        }
        i = j;
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));
    // {前使った遷移,次使う遷移,vector}
    stack<pair<pair<int,int>,vector<int>>> stk;
    stk.push({{-1, 0}, vector<int>{-1}});

    while (stk.size()) {
        auto b = stk.top();
        if (b.first.second == n) {
            stk.pop();
            if (stk.size()) stk.top().first.second += 1;
            continue;
        }
        int last = b.first.first, nxt = b.first.second;
        if (last != -1 and pre[last][L].first != -1) {
            pair<int,int> p = {last, L};
            auto cur = p;
            while (cur.second != 0) {
                res.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(res.begin(), res.end());
            break;
        }

        auto v = b.second;
        if (v[0] == -1) {
            pre[nxt][s[0].size()] = {0, 0};
            stk.push({{nxt, 0}, vector<int>{(int)s[0].size()}});
        }
        else {
            vector<int> vv;
            for (int len : b.second) {
                for (int l : kouho[last][nxt]) {
                    if (len + l > L) continue;
                    int nlen = len+l;
                    if (pre[nxt][nlen].first == -1) {
                        pre[nxt][nlen] = {last, len};
                        vv.push_back(nlen);
                    }
                }
            }
            if (vv.size() == 0) {
                stk.top().first.second += 1;
            }
            else {
                stk.push({{nxt, 0}, vv});
            }
        }
    }

    return res;
}

vector<int> slv2(int n, int L, vector<string> s) {
    vector<int> res;

    vector<int> mx(n);
    vector<vector<int>> kouho(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            string t = s[i] + "$" + s[j];
            auto Z = Zalgo(t);
            int len = 0;
            for (int k = t.size()-1; k >= 0; --k) {
                if (t[k] == '$') break;
                if (Z[k]+k == t.size() and Z[k] != s[0].size()) len = Z[k];
            }
            if (mx[j] < len) {
                mx[j] = len;
                kouho[j].clear();
            }
            if (mx[j] == len) {
                kouho[j].push_back(i);
            }
        }
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));
    queue<pair<int,int>> q;
    for (int i = 0; i < n; ++i) {
        pre[i][s[i].size()] = {0, 0};
        q.push({i, s[i].size()});
    }

    while (q.size()) {
        auto p = q.front(); q.pop();
        if (p.second == L) {
            continue;
        }
        int last = p.first, len = p.second;
        int nlen = len+(s[last].size()-mx[last]);
        if (nlen > L) continue;
        for (int j : kouho[last]) {
            if (pre[j][nlen].first == -1) {
                pre[j][nlen] = p;
                q.push({j, nlen});
            }
        }
    }

    for (int i = 0; i < n; ++i) {
        if (pre[i][L].first != -1) {
            vector<int> nres;
            pair<int,int> p = {i, L};
            auto cur = p;
            while (cur.second != 0) {
                nres.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(nres.begin(), nres.end());
            if (res.size() == 0) res = nres;
            res = min(res, nres);
        }
    }

    return res;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int L,n; cin >> L >> n >> L;
    vector<string> s(n);
    for (int i = 0; i < n; ++i) {
        cin >> s[i];
    }
    vector<int> res;
    if (n <= L) {
        res = slv2(n, L, s);
    }
    else {
        res = slv1(n, L, s);
    }
    cout << res.size() << "\n";
    for (int i = 0; i < res.size(); ++i) {
        if (i) cout << " ";
        cout << res[i];
    }
    cout << "\n";
}
accuracy: 0.6935483870967742
time_ms: 260
memory_kb: 106464
final_rank: 6

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

vector<int> Zalgo(string s){
    int n=s.size();
    vector<int> a(n,0);
    int from=-1,last=-1;
    for(int i=1;i<n;i++){
        int &same=a[i];
        if(from!=-1){
            same=min(a[i-from],last-i);
            same=max(0,same);
        }
        while(i+same<n&&s[same]==s[i+same]){
            same++;
        }
        if(last<i+same){
            last=i+same;
            from=i;
        }
    }
    a[0]=n;
    return a;
}

vector<int> slv1(int n, int L, vector<string> s) {
    vector<int> res;
    vector<pair<string,int>> str; str.reserve(n*s[0].size());
    vector<vector<pair<int,int>>> kouho(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < s[i].size()-1; ++j) {
            str.push_back({s[i].substr(0, j+1), i+1});
            str.push_back({s[i].substr(j+1), -(i+1)});
            kouho[i].push_back({j, s[0].size()});
        }
    }
    sort(str.begin(), str.end());

    for (int i = 0; i < str.size(); ) {
        vector<int> in,out;
        int j = i;
        while (j < str.size() and str[i].first == str[j].first) {
            int pos = abs(str[j].second)-1;
            if (str[j].second > 0) out.push_back(pos);
            else in.push_back(pos);
            j += 1;
        }
        for (int k : in) {
            for (int l : out) {
                kouho[k].push_back({l, s[0].size()-str[i].first.size()});
            }
        }
        i = j;
    }

    for (int i = 0; i < n; ++i) {
        sort(kouho[i].begin(), kouho[i].end(), [&](auto i, auto j){
            if (i.first != j.first) return i < j;
            else return i > j;
        });
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));

    auto dfs = [&](auto dfs, int last, int len) -> void {
        pair<int,int> p = {last, len};
        if (len == L) {
            return;
        }
        for (auto nxt : kouho[last]) {
            if (len+nxt.second > L) continue;
            int nlen = len+nxt.second;
            if (pre[nxt.first][nlen].first == -1) {
                pre[nxt.first][nlen] = p;
                dfs(dfs, nxt.first, nlen);
            }
        }
    };

    for (int i = 0; i < n; ++i) {
        pre[i][s[i].size()] = {0, 0};
        dfs(dfs, i, s[i].size());
    }

    for (int i = 0; i < n; ++i) {
        if (pre[i][L].first != -1) {
            vector<int> nres;
            pair<int,int> p = {i, L};
            auto cur = p;
            while (cur.second != 0) {
                nres.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(nres.begin(), nres.end());
            if (res.size() == 0) res = nres;
            res = min(res, nres);
        }
    }

    return res;
}

vector<int> slv2(int n, int L, vector<string> s) {
    vector<int> res;

    vector<int> mx(n);
    vector<vector<int>> kouho(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            string t = s[i] + "$" + s[j];
            auto Z = Zalgo(t);
            int len = 0;
            for (int k = t.size()-1; k >= 0; --k) {
                if (t[k] == '$') break;
                if (Z[k]+k == t.size() and Z[k] != s[0].size()) len = Z[k];
            }
            if (mx[j] < len) {
                mx[j] = len;
                kouho[j].clear();
            }
            if (mx[j] == len) {
                kouho[j].push_back(i);
            }
        }
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));
    queue<pair<int,int>> q;
    for (int i = 0; i < n; ++i) {
        pre[i][s[i].size()] = {0, 0};
        q.push({i, s[i].size()});
    }

    while (q.size()) {
        auto p = q.front(); q.pop();
        if (p.second == L) {
            auto cur = p;
            while (cur.second != 0) {
                res.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(res.begin(), res.end());
            break;
        }
        int last = p.first, len = p.second;
        int nlen = len+(s[last].size()-mx[last]);
        if (nlen > L) continue;
        for (int j : kouho[last]) {
            if (pre[j][nlen].first == -1) {
                pre[j][nlen] = p;
                q.push({j, nlen});
            }
        }
    }

    return res;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int L,n; cin >> L >> n >> L;
    vector<string> s(n);
    for (int i = 0; i < n; ++i) {
        cin >> s[i];
    }
    vector<int> res;
    if (n <= L) {
        res = slv2(n, L, s);
    }
    else {
        res = slv1(n, L, s);
    }
    cout << res.size() << "\n";
    for (int i = 0; i < res.size(); ++i) {
        if (i) cout << " ";
        cout << res[i];
    }
    cout << "\n";
}
accuracy: 0.6935483870967742
time_ms: 790
memory_kb: 146764
final_rank: 7

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

vector<int> Zalgo(string s){
    int n=s.size();
    vector<int> a(n,0);
    int from=-1,last=-1;
    for(int i=1;i<n;i++){
        int &same=a[i];
        if(from!=-1){
            same=min(a[i-from],last-i);
            same=max(0,same);
        }
        while(i+same<n&&s[same]==s[i+same]){
            same++;
        }
        if(last<i+same){
            last=i+same;
            from=i;
        }
    }
    a[0]=n;
    return a;
}

vector<int> slv1(int n, int L, vector<string> s) {
    vector<int> res;
    vector<pair<string,int>> str; str.reserve(n*s[0].size());
    vector<vector<pair<int,int>>> kouho(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < s[i].size()-1; ++j) {
            str.push_back({s[i].substr(0, j+1), i+1});
            str.push_back({s[i].substr(j+1), -(i+1)});
            kouho[i].push_back({j, s[0].size()});
        }
    }
    sort(str.begin(), str.end());

    for (int i = 0; i < str.size(); ) {
        vector<int> in,out;
        int j = i;
        while (j < str.size() and str[i].first == str[j].first) {
            int pos = abs(str[j].second)-1;
            if (str[j].second > 0) out.push_back(pos);
            else in.push_back(pos);
            j += 1;
        }
        for (int k : in) {
            for (int l : out) {
                kouho[k].push_back({l, s[0].size()-str[i].first.size()});
            }
        }
        i = j;
    }

    for (int i = 0; i < n; ++i) {
        sort(kouho[i].begin(), kouho[i].end());
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));

    auto dfs = [&](auto dfs, int last, int len) -> void {
        pair<int,int> p = {last, len};
        if (len == L) {
            return;
        }
        for (auto nxt : kouho[last]) {
            if (len+nxt.second > L) continue;
            int nlen = len+nxt.second;
            if (pre[nxt.first][nlen].first == -1) {
                pre[nxt.first][nlen] = p;
                dfs(dfs, nxt.first, nlen);
            }
        }
    };

    for (int i = 0; i < n; ++i) {
        pre[i][s[i].size()] = {0, 0};
        dfs(dfs, i, s[i].size());
    }

    for (int i = 0; i < n; ++i) {
        if (pre[i][L].first != -1) {
            vector<int> nres;
            pair<int,int> p = {i, L};
            auto cur = p;
            while (cur.second != 0) {
                nres.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(nres.begin(), nres.end());
            if (res.size() == 0) res = nres;
            res = min(res, nres);
        }
    }

    return res;
}

vector<int> slv2(int n, int L, vector<string> s) {
    vector<int> res;

    vector<int> mx(n);
    vector<vector<int>> kouho(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            string t = s[i] + "$" + s[j];
            auto Z = Zalgo(t);
            int len = 0;
            for (int k = t.size()-1; k >= 0; --k) {
                if (t[k] == '$') break;
                if (Z[k]+k == t.size() and Z[k] != s[0].size()) len = Z[k];
            }
            if (mx[j] < len) {
                mx[j] = len;
                kouho[j].clear();
            }
            if (mx[j] == len) {
                kouho[j].push_back(i);
            }
        }
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));
    queue<pair<int,int>> q;
    for (int i = 0; i < n; ++i) {
        pre[i][s[i].size()] = {0, 0};
        q.push({i, s[i].size()});
    }

    while (q.size()) {
        auto p = q.front(); q.pop();
        if (p.second == L) {
            auto cur = p;
            while (cur.second != 0) {
                res.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(res.begin(), res.end());
            break;
        }
        int last = p.first, len = p.second;
        int nlen = len+(s[last].size()-mx[last]);
        if (nlen > L) continue;
        for (int j : kouho[last]) {
            if (pre[j][nlen].first == -1) {
                pre[j][nlen] = p;
                q.push({j, nlen});
            }
        }
    }

    return res;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int L,n; cin >> L >> n >> L;
    vector<string> s(n);
    for (int i = 0; i < n; ++i) {
        cin >> s[i];
    }
    vector<int> res;
    if (n <= L) {
        res = slv2(n, L, s);
    }
    else {
        res = slv1(n, L, s);
    }
    cout << res.size() << "\n";
    for (int i = 0; i < res.size(); ++i) {
        if (i) cout << " ";
        cout << res[i];
    }
    cout << "\n";
}
accuracy: 0.3709677419354839
time_ms: 810
memory_kb: 146712
final_rank: 12

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

vector<int> Zalgo(string s){
    int n=s.size();
    vector<int> a(n,0);
    int from=-1,last=-1;
    for(int i=1;i<n;i++){
        int &same=a[i];
        if(from!=-1){
            same=min(a[i-from],last-i);
            same=max(0,same);
        }
        while(i+same<n&&s[same]==s[i+same]){
            same++;
        }
        if(last<i+same){
            last=i+same;
            from=i;
        }
    }
    a[0]=n;
    return a;
}

vector<int> slv1(int n, int L, vector<string> s) {
    vector<int> res;
    vector<pair<string,int>> str; str.reserve(n*s[0].size());
    vector<vector<pair<int,int>>> kouho(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < s[i].size()-1; ++j) {
            str.push_back({s[i].substr(0, j+1), i+1});
            str.push_back({s[i].substr(j+1), -(i+1)});
            kouho[i].push_back({j, s[0].size()});
        }
    }
    sort(str.begin(), str.end());

    for (int i = 0; i < str.size(); ) {
        vector<int> in,out;
        int j = i;
        while (j < str.size() and str[i].first == str[j].first) {
            int pos = abs(str[j].second)-1;
            if (str[j].second > 0) out.push_back(pos);
            else in.push_back(pos);
            j += 1;
        }
        for (int k : in) {
            for (int l : out) {
                kouho[k].push_back({l, s[0].size()-str[i].first.size()});
            }
        }
        i = j;
    }

    for (int i = 0; i < n; ++i) {
        sort(kouho[i].begin(), kouho[i].end(), [&](auto i, auto j){
            if (i.first != j.first) return i < j;
            else return i > j;
        });
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));

    auto dfs = [&](auto dfs, int last, int len) -> void {
        if (res.size()) return;
        pair<int,int> p = {last, len};
        if (len == L) {
            auto cur = p;
            while (cur.second != 0) {
                res.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(res.begin(), res.end());
            return;
        }
        for (auto nxt : kouho[last]) {
            if (len+nxt.second > L) continue;
            int nlen = len+nxt.second;
            if (pre[nxt.first][nlen].first == -1) {
                pre[nxt.first][nlen] = p;
                dfs(dfs, nxt.first, nlen);
            }
        }
    };

    for (int i = 0; i < n; ++i) {
        pre[i][s[i].size()] = {0, 0};
        dfs(dfs, i, s[i].size());
    }
    return res;
}

vector<int> slv2(int n, int L, vector<string> s) {
    vector<int> res;

    vector<int> mx(n);
    vector<vector<int>> kouho(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            string t = s[i] + "$" + s[j];
            auto Z = Zalgo(t);
            int len = 0;
            for (int k = t.size()-1; k >= 0; --k) {
                if (t[k] == '$') break;
                if (Z[k]+k == t.size() and Z[k] != s[0].size()) len = Z[k];
            }
            if (mx[j] < len) {
                mx[j] = len;
                kouho[j].clear();
            }
            if (mx[j] == len) {
                kouho[j].push_back(i);
            }
        }
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));
    queue<pair<int,int>> q;
    for (int i = 0; i < n; ++i) {
        pre[i][s[i].size()] = {0, 0};
        q.push({i, s[i].size()});
    }

    while (q.size()) {
        auto p = q.front(); q.pop();
        if (p.second == L) {
            auto cur = p;
            while (cur.second != 0) {
                res.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(res.begin(), res.end());
            break;
        }
        int last = p.first, len = p.second;
        int nlen = len+(s[last].size()-mx[last]);
        if (nlen > L) continue;
        for (int j : kouho[last]) {
            if (pre[j][nlen].first == -1) {
                pre[j][nlen] = p;
                q.push({j, nlen});
            }
        }
    }

    return res;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int L,n; cin >> L >> n >> L;
    vector<string> s(n);
    for (int i = 0; i < n; ++i) {
        cin >> s[i];
    }
    vector<int> res;
    if (n <= L) {
        res = slv2(n, L, s);
    }
    else {
        res = slv1(n, L, s);
    }
    cout << res.size() << "\n";
    for (int i = 0; i < res.size(); ++i) {
        if (i) cout << " ";
        cout << res[i];
    }
    cout << "\n";
}
accuracy: 0.3548387096774194
time_ms: 760
memory_kb: 146720
final_rank: 16

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

vector<int> Zalgo(string s){
    int n=s.size();
    vector<int> a(n,0);
    int from=-1,last=-1;
    for(int i=1;i<n;i++){
        int &same=a[i];
        if(from!=-1){
            same=min(a[i-from],last-i);
            same=max(0,same);
        }
        while(i+same<n&&s[same]==s[i+same]){
            same++;
        }
        if(last<i+same){
            last=i+same;
            from=i;
        }
    }
    a[0]=n;
    return a;
}

vector<int> slv1(int n, int L, vector<string> s) {
    vector<int> res;
    vector<pair<string,int>> str; str.reserve(n*s[0].size());
    vector<vector<pair<int,int>>> kouho(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < s[i].size()-1; ++j) {
            str.push_back({s[i].substr(0, j+1), i+1});
            str.push_back({s[i].substr(j+1), -(i+1)});
            kouho[i].push_back({j, s[0].size()});
        }
    }
    sort(str.begin(), str.end());

    for (int i = 0; i < str.size(); ) {
        vector<int> in,out;
        int j = i;
        while (j < str.size() and str[i].first == str[j].first) {
            int pos = abs(str[j].second)-1;
            if (str[j].second > 0) out.push_back(pos);
            else in.push_back(pos);
            j += 1;
        }
        for (int k : in) {
            for (int l : out) {
                kouho[k].push_back({l, s[0].size()-str[i].first.size()});
            }
        }
        i = j;
    }

    for (int i = 0; i < n; ++i) {
        sort(kouho[i].begin(), kouho[i].end());
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));

    auto dfs = [&](auto dfs, int last, int len) -> void {
        if (res.size()) return;
        pair<int,int> p = {last, len};
        if (len == L) {
            auto cur = p;
            while (cur.second != 0) {
                res.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(res.begin(), res.end());
            return;
        }
        for (auto nxt : kouho[last]) {
            if (len+nxt.second > L) continue;
            int nlen = len+nxt.second;
            if (pre[nxt.first][nlen].first == -1) {
                pre[nxt.first][nlen] = p;
                dfs(dfs, nxt.first, nlen);
            }
        }
    };

    for (int i = 0; i < n; ++i) {
        pre[i][s[i].size()] = {0, 0};
        dfs(dfs, i, s[i].size());
    }
    return res;
}

vector<int> slv2(int n, int L, vector<string> s) {
    vector<int> res;

    vector<int> mx(n);
    vector<vector<int>> kouho(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            string t = s[i] + "$" + s[j];
            auto Z = Zalgo(t);
            int len = 0;
            for (int k = t.size()-1; k >= 0; --k) {
                if (t[k] == '$') break;
                if (Z[k]+k == t.size() and Z[k] != s[0].size()) len = Z[k];
            }
            if (mx[j] < len) {
                mx[j] = len;
                kouho[j].clear();
            }
            if (mx[j] == len) {
                kouho[j].push_back(i);
            }
        }
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));
    queue<pair<int,int>> q;
    for (int i = 0; i < n; ++i) {
        pre[i][s[i].size()] = {0, 0};
        q.push({i, s[i].size()});
    }

    while (q.size()) {
        auto p = q.front(); q.pop();
        if (p.second == L) {
            auto cur = p;
            while (cur.second != 0) {
                res.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(res.begin(), res.end());
            break;
        }
        int last = p.first, len = p.second;
        int nlen = len+(s[last].size()-mx[last]);
        if (nlen > L) continue;
        for (int j : kouho[last]) {
            if (pre[j][nlen].first == -1) {
                pre[j][nlen] = p;
                q.push({j, nlen});
            }
        }
    }

    return res;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int L,n; cin >> L >> n >> L;
    vector<string> s(n);
    for (int i = 0; i < n; ++i) {
        cin >> s[i];
    }
    vector<int> res;
    if (n <= L) {
        res = slv2(n, L, s);
    }
    else {
        res = slv1(n, L, s);
    }
    cout << res.size() << "\n";
    for (int i = 0; i < res.size(); ++i) {
        if (i) cout << " ";
        cout << res[i];
    }
    cout << "\n";
}
accuracy: 0.3709677419354839
time_ms: 790
memory_kb: 146776
final_rank: 11

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

vector<int> Zalgo(string s){
    int n=s.size();
    vector<int> a(n,0);
    int from=-1,last=-1;
    for(int i=1;i<n;i++){
        int &same=a[i];
        if(from!=-1){
            same=min(a[i-from],last-i);
            same=max(0,same);
        }
        while(i+same<n&&s[same]==s[i+same]){
            same++;
        }
        if(last<i+same){
            last=i+same;
            from=i;
        }
    }
    a[0]=n;
    return a;
}

vector<int> slv1(int n, int L, vector<string> s) {
    vector<int> res;
    vector<pair<string,int>> str; str.reserve(n*s[0].size());
    vector<vector<pair<int,int>>> kouho(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < s[i].size()-1; ++j) {
            str.push_back({s[i].substr(0, j+1), i+1});
            str.push_back({s[i].substr(j+1), -(i+1)});
            kouho[i].push_back({j, s[0].size()});
        }
    }
    sort(str.begin(), str.end());

    for (int i = 0; i < str.size(); ) {
        vector<int> in,out;
        int j = i;
        while (j < str.size() and str[i].first == str[j].first) {
            int pos = abs(str[j].second)-1;
            if (str[j].second > 0) out.push_back(pos);
            else in.push_back(pos);
            j += 1;
        }
        for (int k : in) {
            for (int l : out) {
                kouho[k].push_back({l, s[0].size()-str[i].first.size()});
            }
        }
        i = j;
    }

    for (int i = 0; i < n; ++i) {
        sort(kouho[i].begin(), kouho[i].end());
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));
    using P = pair<int,int>;
    queue<P> q;
    for (int i = 0; i < n; ++i) {
        pre[i][s[i].size()] = {0, 0};
        q.push({i, s[i].size()});
    }

    while (q.size()) {
        auto p = q.front(); q.pop();
        if (p.second == L) {
            auto cur = p;
            while (cur.second != 0) {
                res.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(res.begin(), res.end());
            break;
        }
        int last = p.first, len = p.second;

        for (auto nxt : kouho[last]) {
            if (len+nxt.second > L) continue;
            int nlen = len+nxt.second;
            if (pre[nxt.first][nlen].first == -1) {
                pre[nxt.first][nlen] = p;
                q.push({nxt.first, nlen});
            }
        }
    }

    for (int i = 0; i < n; ++i) {
        if (pre[i][L].first != -1) {
            vector<int> nres;
            pair<int,int> p = {i, L};
            auto cur = p;
            while (cur.second != 0) {
                nres.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(nres.begin(), nres.end());
            if (res.size() == 0) res = nres;
            res = min(res, nres);
        }
    }

    return res;
}

vector<int> slv2(int n, int L, vector<string> s) {
    vector<int> res;

    vector<int> mx(n);
    vector<vector<int>> kouho(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            string t = s[i] + "$" + s[j];
            auto Z = Zalgo(t);
            int len = 0;
            for (int k = t.size()-1; k >= 0; --k) {
                if (t[k] == '$') break;
                if (Z[k]+k == t.size() and Z[k] != s[0].size()) len = Z[k];
            }
            if (mx[j] < len) {
                mx[j] = len;
                kouho[j].clear();
            }
            if (mx[j] == len) {
                kouho[j].push_back(i);
            }
        }
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));
    queue<pair<int,int>> q;
    for (int i = 0; i < n; ++i) {
        pre[i][s[i].size()] = {0, 0};
        q.push({i, s[i].size()});
    }

    while (q.size()) {
        auto p = q.front(); q.pop();
        if (p.second == L) {
            auto cur = p;
            while (cur.second != 0) {
                res.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(res.begin(), res.end());
            break;
        }
        int last = p.first, len = p.second;
        int nlen = len+(s[last].size()-mx[last]);
        if (nlen > L) continue;
        for (int j : kouho[last]) {
            if (pre[j][nlen].first == -1) {
                pre[j][nlen] = p;
                q.push({j, nlen});
            }
        }
    }

    return res;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int L,n; cin >> L >> n >> L;
    vector<string> s(n);
    for (int i = 0; i < n; ++i) {
        cin >> s[i];
    }
    vector<int> res;
    if (n <= L) {
        res = slv2(n, L, s);
    }
    else {
        res = slv1(n, L, s);
    }
    cout << res.size() << "\n";
    for (int i = 0; i < res.size(); ++i) {
        if (i) cout << " ";
        cout << res[i];
    }
    cout << "\n";
}
accuracy: 0.6451612903225806
time_ms: 780
memory_kb: 146796
final_rank: 8

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

vector<int> Zalgo(string s){
    int n=s.size();
    vector<int> a(n,0);
    int from=-1,last=-1;
    for(int i=1;i<n;i++){
        int &same=a[i];
        if(from!=-1){
            same=min(a[i-from],last-i);
            same=max(0,same);
        }
        while(i+same<n&&s[same]==s[i+same]){
            same++;
        }
        if(last<i+same){
            last=i+same;
            from=i;
        }
    }
    a[0]=n;
    return a;
}

vector<int> slv1(int n, int L, vector<string> s) {
    vector<int> res;
    vector<pair<string,int>> str; str.reserve(n*s[0].size());
    vector<vector<pair<int,int>>> kouho(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < s[i].size()-1; ++j) {
            str.push_back({s[i].substr(0, j+1), i+1});
            str.push_back({s[i].substr(j+1), -(i+1)});
            kouho[i].push_back({j, s[0].size()});
        }
    }
    sort(str.begin(), str.end());

    for (int i = 0; i < str.size(); ) {
        vector<int> in,out;
        int j = i;
        while (j < str.size() and str[i].first == str[j].first) {
            int pos = abs(str[j].second)-1;
            if (str[j].second > 0) out.push_back(pos);
            else in.push_back(pos);
            j += 1;
        }
        for (int k : in) {
            for (int l : out) {
                kouho[k].push_back({l, s[0].size()-str[i].first.size()});
            }
        }
        i = j;
    }

    for (int i = 0; i < n; ++i) {
        sort(kouho[i].begin(), kouho[i].end());
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));
    using P = pair<int,int>;
    priority_queue<P, vector<P>, greater<P>> q;
    for (int i = 0; i < n; ++i) {
        pre[i][s[i].size()] = {0, 0};
        q.push({i, s[i].size()});
    }

    while (q.size()) {
        auto p = q.top(); q.pop();
        if (p.second == L) {
            auto cur = p;
            while (cur.second != 0) {
                res.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(res.begin(), res.end());
            break;
        }
        int last = p.first, len = p.second;

        for (auto nxt : kouho[last]) {
            if (len+nxt.second > L) continue;
            int nlen = len+nxt.second;
            if (pre[nxt.first][nlen].first == -1) {
                pre[nxt.first][nlen] = p;
                q.push({nxt.first, nlen});
            }
        }
    }

    return res;
}

vector<int> slv2(int n, int L, vector<string> s) {
    vector<int> res;

    vector<int> mx(n);
    vector<vector<int>> kouho(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            string t = s[i] + "$" + s[j];
            auto Z = Zalgo(t);
            int len = 0;
            for (int k = t.size()-1; k >= 0; --k) {
                if (t[k] == '$') break;
                if (Z[k]+k == t.size() and Z[k] != s[0].size()) len = Z[k];
            }
            if (mx[j] < len) {
                mx[j] = len;
                kouho[j].clear();
            }
            if (mx[j] == len) {
                kouho[j].push_back(i);
            }
        }
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));
    queue<pair<int,int>> q;
    for (int i = 0; i < n; ++i) {
        pre[i][s[i].size()] = {0, 0};
        q.push({i, s[i].size()});
    }

    while (q.size()) {
        auto p = q.front(); q.pop();
        if (p.second == L) {
            auto cur = p;
            while (cur.second != 0) {
                res.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(res.begin(), res.end());
            break;
        }
        int last = p.first, len = p.second;
        int nlen = len+(s[last].size()-mx[last]);
        if (nlen > L) continue;
        for (int j : kouho[last]) {
            if (pre[j][nlen].first == -1) {
                pre[j][nlen] = p;
                q.push({j, nlen});
            }
        }
    }

    return res;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int L,n; cin >> L >> n >> L;
    vector<string> s(n);
    for (int i = 0; i < n; ++i) {
        cin >> s[i];
    }
    vector<int> res;
    if (n <= L) {
        res = slv2(n, L, s);
    }
    else {
        res = slv1(n, L, s);
    }
    cout << res.size() << "\n";
    for (int i = 0; i < res.size(); ++i) {
        if (i) cout << " ";
        cout << res[i];
    }
    cout << "\n";
}
accuracy: 0.46774193548387094
time_ms: 780
memory_kb: 146752
final_rank: 9

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

vector<int> Zalgo(string s){
    int n=s.size();
    vector<int> a(n,0);
    int from=-1,last=-1;
    for(int i=1;i<n;i++){
        int &same=a[i];
        if(from!=-1){
            same=min(a[i-from],last-i);
            same=max(0,same);
        }
        while(i+same<n&&s[same]==s[i+same]){
            same++;
        }
        if(last<i+same){
            last=i+same;
            from=i;
        }
    }
    a[0]=n;
    return a;
}

vector<int> slv1(int n, int L, vector<string> s) {
    vector<int> res;
    vector<pair<string,int>> str; str.reserve(n*s[0].size());
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < s[i].size()-1; ++j) {
            str.push_back({s[i].substr(0, j+1), i+1});
            str.push_back({s[i].substr(j+1), -(i+1)});
        }
    }
    sort(str.begin(), str.end());

    vector<vector<pair<int,int>>> kouho(n);

    for (int i = 0; i < str.size(); ) {
        vector<int> in,out;
        int j = i;
        while (j < str.size() and str[i].first == str[j].first) {
            int pos = abs(str[j].second)-1;
            if (str[j].second > 0) out.push_back(pos);
            else in.push_back(pos);
            j += 1;
        }
        for (int k : in) {
            for (int l : out) {
                kouho[k].push_back({l, s[0].size()-str[i].first.size()});
            }
        }
        i = j;
    }

    for (int i = 0; i < n; ++i) {
        sort(kouho[i].begin(), kouho[i].end());
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));
    queue<pair<int,int>> q;
    for (int i = 0; i < n; ++i) {
        pre[i][s[i].size()] = {0, 0};
        q.push({i, s[i].size()});
    }

    while (q.size()) {
        auto p = q.front(); q.pop();
        if (p.second == L) {
            auto cur = p;
            while (cur.second != 0) {
                res.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(res.begin(), res.end());
            break;
        }
        int last = p.first, len = p.second;

        for (auto nxt : kouho[last]) {
            if (len+nxt.second > L) continue;
            int nlen = len+nxt.second;
            if (pre[nxt.first][nlen].first == -1) {
                pre[nxt.first][nlen] = p;
                q.push({nxt.first, nlen});
            }
        }
    }

    return res;
}

vector<int> slv2(int n, int L, vector<string> s) {
    vector<int> res;

    vector<int> mx(n);
    vector<vector<int>> kouho(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            string t = s[i] + "$" + s[j];
            auto Z = Zalgo(t);
            int len = 0;
            for (int k = t.size()-1; k >= 0; --k) {
                if (t[k] == '$') break;
                if (Z[k]+k == t.size() and Z[k] != s[0].size()) len = Z[k];
            }
            if (mx[j] < len) {
                mx[j] = len;
                kouho[j].clear();
            }
            if (mx[j] == len) {
                kouho[j].push_back(i);
            }
        }
    }

    vector<vector<pair<int,int>>> pre(n, vector<pair<int,int>>(L+1, {-1, -1}));
    queue<pair<int,int>> q;
    for (int i = 0; i < n; ++i) {
        pre[i][s[i].size()] = {0, 0};
        q.push({i, s[i].size()});
    }

    while (q.size()) {
        auto p = q.front(); q.pop();
        if (p.second == L) {
            auto cur = p;
            while (cur.second != 0) {
                res.push_back(cur.first);
                cur = pre[cur.first][cur.second];
            }
            reverse(res.begin(), res.end());
            break;
        }
        int last = p.first, len = p.second;
        int nlen = len+(s[last].size()-mx[last]);
        if (nlen > L) continue;
        for (int j : kouho[last]) {
            if (pre[j][nlen].first == -1) {
                pre[j][nlen] = p;
                q.push({j, nlen});
            }
        }
    }

    return res;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int L,n; cin >> L >> n >> L;
    vector<string> s(n);
    for (int i = 0; i < n; ++i) {
        cin >> s[i];
    }
    vector<int> res;
    if (n <= L) {
        res = slv2(n, L, s);
    }
    else {
        res = slv1(n, L, s);
    }
    cout << res.size() << "\n";
    for (int i = 0; i < res.size(); ++i) {
        if (i) cout << " ";
        cout << res[i];
    }
    cout << "\n";
}
accuracy: 0.3870967741935484
time_ms: 780
memory_kb: 145936
final_rank: 10

code_snippet: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"


using namespace std;

constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
//constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-12;

//int N, M, K, T, H, W, L, R;
long long int N, M, K, T, H, W, L, R;

vector<string>s;

class Z_algorithm {
public:
	vector<int>v;
	Z_algorithm(string s) {
		v.resize(s.size(), 0);
		v[0] = s.size();
		int i = 1, j = 0;
		while (i < s.size()) {
			while (i + j < s.size() && s[i + j] == s[j]) {
				j++;
			}
			v[i] = j;
			if (j == 0) {
				i++;
				continue;
			}
			int k = 1;
			while (i + k < s.size() && k + v[k] < j) {
				v[i + k] = v[k];
				k++;
			}
			i += k;
			j -= k;
		}
	}
};

int border = 1300;

vector<int>func1() {
	map<string, int>mp;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < L; j++) {
			mp[s[i].substr(0, j)];
			mp[s[i].substr(L - j, j)];
		}
	}
	int cnt = 0;
	for (auto &i : mp) {
		i.second = cnt++;
	}
	vector<vector<int>>pre(N, vector<int>(L));
	vector<vector<int>>suf(N, vector<int>(L));
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < L; j++) {
			pre[i][j] = mp[s[i].substr(0, j)];
			suf[i][j] = mp[s[i].substr(L - j, j)];
		}
	}
	vector<vector<int>>dp(cnt, vector<int>(K + 1, MOD));
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < L; j++) {
			dp[pre[i][j]][L] = min(dp[pre[i][j]][L], i);
		}
	}
	for (int j = L + 1; j <= K; j++) {
		for (int i = 0; i < N; i++) {
			bool flag = false;
			for (int k = 0; k < L; k++) {
				if (dp[suf[i][k]][j - L + k] < MOD)flag = true;
			}
			if (flag) {
				for (int k = 0; k < L; k++) {
					dp[pre[i][k]][j] = min(dp[pre[i][k]][j], i);
				}
			}
		}
	}
	int cn = dp[pre[0][0]][K];
	vector<int>cand(K + 1);
	cand[K] = 1;
	vector<int>ret;
	ret.push_back(cn);
	if (L != K) {
		while (1) {
			vector<int>ncand(K + 1);
			int nx = MOD;
			for (int i = 0; i <= K; i++) {
				if (!cand[i])continue;
				for (int j = 0; j < L; j++) {
					if (i - L + j >= 0)nx = min(nx, dp[suf[cn][j]][i - L + j]);
				}
			}
			for (int i = 0; i <= K; i++) {
				if (!cand[i])continue;
				for (int j = 0; j < L; j++) {
					if (i - L + j >= 0) {
						if (dp[suf[cn][j]][i - L + j] == nx) {
							ncand[i - L + j] = 1;
						}
					}
				}
			}
			cand = ncand;
			ret.push_back(nx);
			cn = nx;
			if (cand[L])break;
		}
	}
	return ret;
}

vector<int>func2() {
	vector<vector<bool>>dp(N, vector<bool>(K + 1));
	for (int i = 0; i < N; i++)dp[i][L] = true;
	vector<vector<int>>num(N, vector<int>(N));
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			Z_algorithm z(s[j] + s[i]);
			for (int k = 1; k < L; k++) {
				if (z.v[L * 2 - k] == k) {
					num[i][j] = k;
				}
			}
		}
	}
	for (int j = L + 1; j <= K; j++) {
		for (int i = 0; i < N; i++) {
			for (int k = 0; k < N; k++) {
		//		if (i == k)continue;
				if (dp[k][j - L + num[i][k]]) {
					dp[i][j] = true;
					break;
				}
			}
		}
	}
	vector<int>ret;
	for (int i = 0; i < N; i++) {
		if (dp[i].back()) {
			ret.push_back(i);
			break;
		}
	}
	int cn = ret.back();
	int c = K;
	while (c != L) {
		for (int i = 0; i < N; i++) {
		//	if (cn == i)continue;
			if (dp[i][c - L + num[cn][i]]) {
				c -= L - num[cn][i];
				ret.push_back(i);
				cn = i;
				break;
			}
		}
	}
	return ret;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> L >> N >> K;
	s.resize(N);
	for (auto &i : s)cin >> i;
	if (N > border) {
		auto ret1 = func1();
		cout << ret1.size() << endl;
		for (auto i : ret1) {
			cout << i << " ";
		}
		cout << endl;
	}
	else {
		auto ret2 = func2();
		cout << ret2.size() << endl;
		for (auto i : ret2) {
			cout << i << " ";
		}
		cout << endl;
	}
}
accuracy: 1
time_ms: 210
memory_kb: 21616
final_rank: 1

code_snippet: #include <bits/stdc++.h>

using namespace std;

vector<int> z_func(string s)
{
    vector<int> z(s.size());
    int L = 0, R = 0;
    for (int i = 1; i < s.size(); i++)
    {
        z[i] = max(0, min(z[i - L], R - i));
        while (i + z[i] < s.size() && s[i + z[i]] == s[z[i]])
            z[i]++;
        if (i + z[i] > R)
        {
            R = i + z[i];
            L = i;
        }
    }
    return z;
}

void solve1(int l, int n, int k, vector<string> s)
{
    const int MOD = 1e9 + 239;
    const int BASE = 1e6 + 3;

    vector<int> deg(l + 1);
    deg[0] = 1;
    for (int i = 1; i <= l; i++) deg[i] = 1ll * deg[i - 1] * BASE % MOD;

    vector<vector<int> > pref_hash(n, vector<int>(l));
    vector<vector<int> > suff_hash(n, vector<int>(l));

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < l; j++)
        {
            if (j) pref_hash[i][j] = 1ll * pref_hash[i][j - 1] * BASE % MOD;
            pref_hash[i][j] = (pref_hash[i][j] + s[i][j]) % MOD;
        }
        for (int j = l - 1; j >= 0; j--)
        {
            if (j + 1 < l) suff_hash[i][j] = suff_hash[i][j + 1];
            suff_hash[i][j] = (suff_hash[i][j] + 1ll * s[i][j] * deg[l - 1 - j]) % MOD;
        }
    }

    vector<vector<int> > dp(k + 1, vector<int>(n, n));
    vector<vector<map<int, int> > > possible(k + 1, vector<map<int, int> >(l + 1));
    for (int i = 0; i < n; i++)
        dp[l][i] = 0;
    for (int len = l; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            int h = 0;
            for (int inter = 0; inter < l; inter++)
            {
                int olen = len - (l - inter);
                if (possible[olen][inter].find(h) != possible[olen][inter].end())
                {
                    dp[len][i] = min(dp[len][i], possible[olen][inter][h]);
                }
                h = (h + 1ll * s[i][l - 1 - inter] * deg[inter]) % MOD;
            }
            if (dp[len][i] != n)
            {
                h = 0;
                for (int j = 0; j < l; j++)
                {
                    if (possible[len][j].find(h) == possible[len][j].end())
                        possible[len][j][h] = i;
                    h = (1ll * h * BASE + s[i][j]) % MOD;
                }
            }
        }
    }
    vector<vector<vector<int> > > paths(k + 1, vector<vector<int> >(n));
    for (int i = 0; i < n; i++)
        paths[l][i].push_back(i);

    for (int len = l + 1; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            if (dp[len][i] == n) continue;
            int j = dp[len][i];
            //cout << len << " " << i << " " << j << endl;
            paths[len][i].push_back(i);
            vector<int> res = {n};
            if (dp[len - l][j] != n) res = paths[len - l][j];
            for (int inter = 1; inter < l; inter++)
            {
                if (suff_hash[i][l - inter] == pref_hash[j][inter - 1] &&
                    dp[len - l + inter][j] != n)
                {
                    //cout << "! " << inter << endl;
                    res = min(res, paths[len - l + inter][j]);
                }
            }
            //cout << res.size() << endl;
            assert(res[0] != n);
            for (auto e : res) paths[len][i].push_back(e);
        }
    }

    vector<int> ans;
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] != n)
        {
            ans = paths[k][i];
            break;
        }
    }
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

void solve2(int l, int n, int k, vector<string> s)
{
    vector<vector<int> > dp(k + 1, vector<int>(n));
    vector<vector<int> > deep(n + 1, vector<int>(n + 1));
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            string ss = s[i] + s[j];
            vector<int> z = z_func(ss);
            deep[j][i] = l;
            for (int k = l + 1; k < 2 * l; k++)
            {
                if (k + z[k] == 2 * l)
                {
                    deep[j][i] = k - l;
                    break;
                }
            }
        }
    }
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < n; i++)
            {
                int nlen = len + deep[i][j];
                if (nlen <= k && dp[len][j] && !dp[nlen][i])
                {
                    dp[nlen][i] = 1;
                }
            }
        }
    }
    int idx = -1;
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i])
        {
            idx = i;
            break;
        }
    }
    assert(idx != -1);
    vector<int> ans;
    while (k > l)
    {
        int nid = -1;
        for (int i = 0; i < n; i++)
        {
            int adds = deep[idx][i];
            if (adds == 0 || !dp[k - deep[idx][i]][i]) continue;
            nid = i;
            break;
        }
        assert(nid != -1);
        assert(deep[idx][nid] != 0);
        ans.push_back(idx);
        k -= deep[idx][nid];
        idx = nid;
    }
    assert(k == l);
    ans.push_back(idx);
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int l, n, k;
    cin >> l >> n >> k;
    vector<string> s(n);
    for (int i = 0; i < n; i++)
    {
        cin >> s[i];
    }
    if (n > 1500)
        solve1(l, n, k, s);
    else
        solve2(l, n, k, s);
}

/*

5 3 10
abbab
babbb
aaaab

5 3 6
abbab
babbb
ddddd
*/
accuracy: 1
time_ms: 280
memory_kb: 29060
final_rank: 2

code_snippet: #include <bits/stdc++.h>

using namespace std;

vector<int> z_func(string s)
{
    vector<int> z(s.size());
    int L = 0, R = 0;
    for (int i = 1; i < s.size(); i++)
    {
        z[i] = max(0, min(z[i - L], R - i));
        while (i + z[i] < s.size() && s[i + z[i]] == s[z[i]])
            z[i]++;
        if (i + z[i] > R)
        {
            R = i + z[i];
            L = i;
        }
    }
    return z;
}

void solve1(int l, int n, int k, vector<string> s)
{
    const int MOD = 1e9 + 239;
    const int BASE = 1e6 + 3;

    vector<int> deg(l + 1);
    deg[0] = 1;
    for (int i = 1; i <= l; i++) deg[i] = 1ll * deg[i - 1] * BASE % MOD;

    vector<vector<int> > pref_hash(n, vector<int>(l));
    vector<vector<int> > suff_hash(n, vector<int>(l));

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < l; j++)
        {
            if (j) pref_hash[i][j] = 1ll * pref_hash[i][j - 1] * BASE % MOD;
            pref_hash[i][j] = (pref_hash[i][j] + s[i][j]) % MOD;
        }
        for (int j = l - 1; j >= 0; j--)
        {
            if (j + 1 < l) suff_hash[i][j] = suff_hash[i][j + 1];
            suff_hash[i][j] = (suff_hash[i][j] + 1ll * s[i][j] * deg[l - 1 - j]) % MOD;
        }
    }

    vector<vector<int> > dp(k + 1, vector<int>(n, n));
    vector<vector<map<int, int> > > possible(k + 1, vector<map<int, int> >(l + 1));
    for (int i = 0; i < n; i++)
        dp[l][i] = 0;
    for (int len = l; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            int h = 0;
            for (int inter = 0; inter < l; inter++)
            {
                int olen = len - (l - inter);
                if (possible[olen][inter].find(h) != possible[olen][inter].end())
                {
                    dp[len][i] = min(dp[len][i], possible[olen][inter][h]);
                }
                h = (h + 1ll * s[i][l - 1 - inter] * deg[inter]) % MOD;
            }
            if (dp[len][i] != n)
            {
                h = 0;
                for (int j = 0; j < l; j++)
                {
                    if (possible[len][j].find(h) == possible[len][j].end())
                        possible[len][j][h] = i;
                    h = (1ll * h * BASE + s[i][j]) % MOD;
                }
            }
        }
    }
    vector<vector<vector<int> > > paths(k + 1, vector<vector<int> >(n));
    for (int i = 0; i < n; i++)
        paths[l][i].push_back(i);

    for (int len = l + 1; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            if (dp[len][i] == n) continue;
            int j = dp[len][i];
            //cout << len << " " << i << " " << j << endl;
            paths[len][i].push_back(i);
            vector<int> res = {n};
            if (dp[len - l][j] != n) res = paths[len - l][j];
            for (int inter = 1; inter < l; inter++)
            {
                if (suff_hash[i][l - inter] == pref_hash[j][inter - 1] &&
                    dp[len - l + inter][j] != n)
                {
                    //cout << "! " << inter << endl;
                    res = min(res, paths[len - l + inter][j]);
                }
            }
            //cout << res.size() << endl;
            assert(res[0] != n);
            for (auto e : res) paths[len][i].push_back(e);
        }
    }

    vector<int> ans;
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] != n)
        {
            ans = paths[k][i];
            break;
        }
    }
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

void solve2(int l, int n, int k, vector<string> s)
{
    vector<vector<int> > dp(k + 1, vector<int>(n));
    vector<vector<int> > deep(n + 1, vector<int>(n + 1));
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            string ss = s[i] + s[j];
            vector<int> z = z_func(ss);
            deep[j][i] = l;
            for (int k = l + 1; k < 2 * l; k++)
            {
                if (k + z[k] == 2 * l)
                {
                    deep[j][i] = k - l;
                    break;
                }
            }
        }
    }
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < n; i++)
            {
                int nlen = len + deep[i][j];
                if (nlen <= k && dp[len][j] && !dp[nlen][i])
                {
                    dp[nlen][i] = 1;
                }
            }
        }
    }
    int idx = -1;
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i])
        {
            idx = i;
            break;
        }
    }
    assert(idx != -1);
    vector<int> ans;
    while (k > l)
    {
        int nid = -1;
        for (int i = 0; i < n; i++)
        {
            int adds = deep[idx][i];
            if (adds == 0 || !dp[k - deep[idx][i]][i]) continue;
            nid = i;
            break;
        }
        assert(nid != -1);
        assert(deep[idx][nid] != 0);
        ans.push_back(idx);
        k -= deep[idx][nid];
        idx = nid;
    }
    assert(k == l);
    ans.push_back(idx);
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int l, n, k;
    cin >> l >> n >> k;
    vector<string> s(n);
    for (int i = 0; i < n; i++)
    {
        cin >> s[i];
    }
    if (n > 1200)
        solve1(l, n, k, s);
    else
        solve2(l, n, k, s);
}

/*

5 3 10
abbab
babbb
aaaab

5 3 6
abbab
babbb
ddddd
*/
accuracy: 1
time_ms: 280
memory_kb: 29092
final_rank: 3

code_snippet: #include <bits/stdc++.h>

using namespace std;

vector<int> z_func(string s)
{
    vector<int> z(s.size());
    int L = 0, R = 0;
    for (int i = 1; i < s.size(); i++)
    {
        z[i] = max(0, min(z[i - L], R - i));
        while (i + z[i] < s.size() && s[i + z[i]] == s[z[i]])
            z[i]++;
        if (i + z[i] > R)
        {
            R = i + z[i];
            L = i;
        }
    }
    return z;
}

void solve1(int l, int n, int k, vector<string> s)
{
    const int MOD = 1e9 + 239;
    const int BASE = 1e6 + 3;

    vector<int> deg(l + 1);
    deg[0] = 1;
    for (int i = 1; i <= l; i++) deg[i] = 1ll * deg[i - 1] * BASE % MOD;

    vector<vector<int> > pref_hash(n, vector<int>(l));
    vector<vector<int> > suff_hash(n, vector<int>(l));

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < l; j++)
        {
            if (j) pref_hash[i][j] = 1ll * pref_hash[i][j - 1] * BASE % MOD;
            pref_hash[i][j] = (pref_hash[i][j] + s[i][j]) % MOD;
        }
        for (int j = l - 1; j >= 0; j--)
        {
            if (j + 1 < l) suff_hash[i][j] = suff_hash[i][j + 1];
            suff_hash[i][j] = (suff_hash[i][j] + 1ll * s[i][j] * deg[l - 1 - j]) % MOD;
        }
    }

    vector<vector<int> > dp(k + 1, vector<int>(n, n));
    vector<vector<map<int, int> > > possible(k + 1, vector<map<int, int> >(l + 1));
    for (int i = 0; i < n; i++)
        dp[l][i] = 0;
    for (int len = l; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            int h = 0;
            for (int inter = 0; inter < l; inter++)
            {
                int olen = len - (l - inter);
                if (possible[olen][inter].find(h) != possible[olen][inter].end())
                {
                    dp[len][i] = min(dp[len][i], possible[olen][inter][h]);
                }
                h = (h + 1ll * s[i][l - 1 - inter] * deg[inter]) % MOD;
            }
            if (dp[len][i] != n)
            {
                h = 0;
                for (int j = 0; j < l; j++)
                {
                    if (possible[len][j].find(h) == possible[len][j].end())
                        possible[len][j][h] = i;
                    h = (1ll * h * BASE + s[i][j]) % MOD;
                }
            }
        }
    }
    vector<vector<vector<int> > > paths(k + 1, vector<vector<int> >(n));
    for (int i = 0; i < n; i++)
        paths[l][i].push_back(i);

    for (int len = l + 1; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            if (dp[len][i] == n) continue;
            int j = dp[len][i];
            //cout << len << " " << i << " " << j << endl;
            paths[len][i].push_back(i);
            vector<int> res = {n};
            if (dp[len - l][j] != n) res = paths[len - l][j];
            for (int inter = 1; inter < l; inter++)
            {
                if (suff_hash[i][l - inter] == pref_hash[j][inter - 1] &&
                    dp[len - l + inter][j] != n)
                {
                    //cout << "! " << inter << endl;
                    res = min(res, paths[len - l + inter][j]);
                }
            }
            //cout << res.size() << endl;
            assert(res[0] != n);
            for (auto e : res) paths[len][i].push_back(e);
        }
    }

    vector<int> ans;
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] != n)
        {
            ans = paths[k][i];
            break;
        }
    }
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

void solve2(int l, int n, int k, vector<string> s)
{
    vector<vector<int> > dp(k + 1, vector<int>(n));
    vector<vector<int> > deep(n + 1, vector<int>(n + 1));
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            string ss = s[i] + s[j];
            vector<int> z = z_func(ss);
            deep[j][i] = l;
            for (int k = l + 1; k < 2 * l; k++)
            {
                if (k + z[k] == 2 * l)
                {
                    deep[j][i] = k - l;
                    break;
                }
            }
        }
    }
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < n; i++)
            {
                int nlen = len + deep[i][j];
                if (nlen <= k && dp[len][j] && !dp[nlen][i])
                {
                    dp[nlen][i] = 1;
                }
            }
        }
    }
    int idx = -1;
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i])
        {
            idx = i;
            break;
        }
    }
    assert(idx != -1);
    vector<int> ans;
    while (k > l)
    {
        int nid = -1;
        for (int i = 0; i < n; i++)
        {
            int adds = deep[idx][i];
            if (adds == 0 || !dp[k - deep[idx][i]][i]) continue;
            nid = i;
            break;
        }
        assert(nid != -1);
        assert(deep[idx][nid] != 0);
        ans.push_back(idx);
        k -= deep[idx][nid];
        idx = nid;
    }
    assert(k == l);
    ans.push_back(idx);
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int l, n, k;
    cin >> l >> n >> k;
    vector<string> s(n);
    for (int i = 0; i < n; i++)
    {
        cin >> s[i];
    }
    if (n > 2000)
        solve1(l, n, k, s);
    else
        solve2(l, n, k, s);
}

/*

5 3 10
abbab
babbb
aaaab

5 3 6
abbab
babbb
ddddd
*/
accuracy: 1
time_ms: 970
memory_kb: 19456
final_rank: 5

code_snippet: #include <bits/stdc++.h>

using namespace std;

vector<int> z_func(string s)
{
    vector<int> z(s.size());
    int L = 0, R = 0;
    for (int i = 1; i < s.size(); i++)
    {
        z[i] = max(0, min(z[i - L], R - i));
        while (i + z[i] < s.size() && s[i + z[i]] == s[z[i]])
            z[i]++;
        if (i + z[i] > R)
        {
            R = i + z[i];
            L = i;
        }
    }
    return z;
}

void solve1(int l, int n, int k, vector<string> s)
{
    const int MOD = 1e9 + 239;
    const int BASE = 1e6 + 3;

    vector<int> deg(l + 1);
    deg[0] = 1;
    for (int i = 1; i <= l; i++) deg[i] = 1ll * deg[i - 1] * BASE % MOD;

    vector<vector<int> > pref_hash(n, vector<int>(l));
    vector<vector<int> > suff_hash(n, vector<int>(l));

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < l; j++)
        {
            if (j) pref_hash[i][j] = 1ll * pref_hash[i][j - 1] * BASE % MOD;
            pref_hash[i][j] = (pref_hash[i][j] + s[i][j]) % MOD;
        }
        for (int j = l - 1; j >= 0; j--)
        {
            if (j + 1 < l) suff_hash[i][j] = suff_hash[i][j + 1];
            suff_hash[i][j] = (suff_hash[i][j] + 1ll * s[i][j] * deg[l - 1 - j]) % MOD;
        }
    }

    vector<vector<int> > dp(k + 1, vector<int>(n, n));
    vector<vector<map<int, int> > > possible(k + 1, vector<map<int, int> >(l + 1));
    for (int i = 0; i < n; i++)
        dp[l][i] = 0;
    for (int len = l; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            int h = 0;
            for (int inter = 0; inter < l; inter++)
            {
                int olen = len - (l - inter);
                if (possible[olen][inter].find(h) != possible[olen][inter].end())
                {
                    dp[len][i] = min(dp[len][i], possible[olen][inter][h]);
                }
                h = (h + 1ll * s[i][l - 1 - inter] * deg[inter]) % MOD;
            }
            if (dp[len][i] != n)
            {
                h = 0;
                for (int j = 0; j < l; j++)
                {
                    if (possible[len][j].find(h) == possible[len][j].end())
                        possible[len][j][h] = i;
                    h = (1ll * h * BASE + s[i][j]) % MOD;
                }
            }
        }
    }
    vector<vector<vector<int> > > paths(k + 1, vector<vector<int> >(n));
    for (int i = 0; i < n; i++)
        paths[l][i].push_back(i);

    for (int len = l + 1; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            if (dp[len][i] == n) continue;
            int j = dp[len][i];
            //cout << len << " " << i << " " << j << endl;
            paths[len][i].push_back(i);
            vector<int> res = {n};
            if (dp[len - l][j] != n) res = paths[len - l][j];
            for (int inter = 1; inter < l; inter++)
            {
                if (suff_hash[i][l - inter] == pref_hash[j][inter - 1] &&
                    dp[len - l + inter][j] != n)
                {
                    //cout << "! " << inter << endl;
                    res = min(res, paths[len - l + inter][j]);
                }
            }
            //cout << res.size() << endl;
            assert(res[0] != n);
            for (auto e : res) paths[len][i].push_back(e);
        }
    }

    vector<int> ans;
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] != n)
        {
            ans = paths[k][i];
            break;
        }
    }
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

void solve2(int l, int n, int k, vector<string> s)
{
    vector<vector<int> > dp(k + 1, vector<int>(n));
    vector<vector<int> > deep(n + 1, vector<int>(n + 1));
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            string ss = s[i] + s[j];
            vector<int> z = z_func(ss);
            deep[j][i] = l;
            for (int k = l + 1; k < 2 * l; k++)
            {
                if (k + z[k] == 2 * l)
                {
                    deep[j][i] = k - l;
                    break;
                }
            }
        }
    }
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < n; i++)
            {
                int nlen = len + deep[i][j];
                if (nlen <= k && dp[len][j] && !dp[nlen][i])
                {
                    dp[nlen][i] = 1;
                }
            }
        }
    }
    int idx = -1;
    string res = "";
    res += (char)('z' + 1);
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] && s[i] < res)
        {
            res = s[i];
            idx = i;
            break;
        }
    }
    assert(idx != -1);
    vector<int> ans;
    while (k > l)
    {
        string q = "";
        q += (char)('z' + 1);
        int nid = -1;
        for (int i = 0; i < n; i++)
        {
            int adds = deep[idx][i];
            if (adds == 0 || !dp[k - deep[idx][i]][i]) continue;
            string y = "";
            for (int p = l - deep[idx][i]; p < l; p++)
                y += s[i][p];
            q = y;
            nid = i;
            break;
        }
        res += q;
        assert(nid != -1);
        assert(deep[idx][nid] != 0);
        ans.push_back(idx);
        k -= deep[idx][nid];
        idx = nid;
    }
    assert(k == l);
    ans.push_back(idx);
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int l, n, k;
    cin >> l >> n >> k;
    vector<string> s(n);
    for (int i = 0; i < n; i++)
    {
        cin >> s[i];
    }
    if (n > 1500)
        solve1(l, n, k, s);
    else
        solve2(l, n, k, s);
}

/*

5 3 10
abbab
babbb
aaaab

5 3 6
abbab
babbb
ddddd
*/
accuracy: 1
time_ms: 290
memory_kb: 29088
final_rank: 4

code_snippet: #include <bits/stdc++.h>

using namespace std;

vector<int> z_func(string s)
{
    vector<int> z(s.size());
    int L = 0, R = 0;
    for (int i = 1; i < s.size(); i++)
    {
        z[i] = max(0, min(z[i - L], R - i));
        while (i + z[i] < s.size() && s[i + z[i]] == s[z[i]])
            z[i]++;
        if (i + z[i] > R)
        {
            R = i + z[i];
            L = i;
        }
    }
    return z;
}

void solve1(int l, int n, int k, vector<string> s)
{
    const int MOD = 1e9 + 9;
    const int BASE = 1e6 + 3;

    vector<int> deg(l + 1);
    deg[0] = 1;
    for (int i = 1; i <= l; i++) deg[i] = 1ll * deg[i - 1] * BASE % MOD;

    vector<vector<int> > pref_hash(n, vector<int>(l));
    vector<vector<int> > suff_hash(n, vector<int>(l));

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < l; j++)
        {
            if (j) pref_hash[i][j] = 1ll * pref_hash[i][j - 1] * BASE % MOD;
            pref_hash[i][j] = (pref_hash[i][j] + s[i][j]) % MOD;
        }
        for (int j = l - 1; j >= 0; j--)
        {
            if (j + 1 < l) suff_hash[i][j] = suff_hash[i][j + 1];
            suff_hash[i][j] = (suff_hash[i][j] + 1ll * s[i][j] * deg[l - 1 - j]) % MOD;
        }
    }

    vector<vector<int> > dp(k + 1, vector<int>(n, n));
    vector<vector<map<int, int> > > possible(k + 1, vector<map<int, int> >(l + 1));
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            int h = 0;
            for (int inter = 0; inter < l; inter++)
            {
                int olen = len - (l - inter);
                if (possible[olen][inter].find(h) != possible[olen][inter].end())
                {
                    dp[len][i] = min(dp[len][i], possible[olen][inter][h]);
                }
                h = (h + 1ll * s[i][l - 1 - inter] * deg[inter]) % MOD;
            }
            if (dp[len][i])
            {
                h = 0;
                for (int j = 0; j < l; j++)
                {
                    if (possible[len][j].find(h) == possible[len][j].end())
                        possible[len][j][h] = i;
                    h = (1ll * h * BASE + s[i][j]) % MOD;
                }
            }
        }
    }
    vector<vector<vector<int> > > paths(k + 1, vector<vector<int> >(n));
    for (int i = 0; i < n; i++)
        paths[l][i].push_back(i);

    for (int len = l + 1; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            if (dp[len][i] == n) continue;
            int j = dp[len][i];
            paths[len][i].push_back(i);
            vector<int> res = {n};
            if (dp[len - l][j] != n) res = paths[len - l][j];
            for (int inter = 1; inter < l; inter++)
            {
                if (suff_hash[i][l - inter] == pref_hash[j][inter - 1] &&
                    dp[len - l + inter][j] != n)
                {
                    res = min(res, paths[len - l + inter][j]);
                }
            }
            assert(res[0] != n);
            for (auto e : res) paths[len][i].push_back(e);
        }
    }

    vector<int> ans;
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] != n)
        {
            ans = paths[k][i];
            break;
        }
    }
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

void solve2(int l, int n, int k, vector<string> s)
{
    vector<vector<int> > dp(k + 1, vector<int>(n));
    vector<vector<int> > deep(n + 1, vector<int>(n + 1));
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            string ss = s[i] + s[j];
            vector<int> z = z_func(ss);
            deep[j][i] = l;
            for (int k = l + 1; k < 2 * l; k++)
            {
                if (k + z[k] == 2 * l)
                {
                    deep[j][i] = k - l;
                    break;
                }
            }
        }
    }
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < n; i++)
            {
                int nlen = len + deep[i][j];
                if (nlen <= k && dp[len][j] && !dp[nlen][i])
                {
                    dp[nlen][i] = 1;
                }
            }
        }
    }
    int idx = -1;
    string res = "";
    res += (char)('z' + 1);
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] && s[i] < res)
        {
            res = s[i];
            idx = i;
            break;
        }
    }
    assert(idx != -1);
    vector<int> ans;
    while (k > l)
    {
        string q = "";
        q += (char)('z' + 1);
        int nid = -1;
        for (int i = 0; i < n; i++)
        {
            int adds = deep[idx][i];
            if (adds == 0 || !dp[k - deep[idx][i]][i]) continue;
            string y = "";
            for (int p = l - deep[idx][i]; p < l; p++)
                y += s[i][p];
            q = y;
            nid = i;
            break;
        }
        res += q;
        assert(nid != -1);
        assert(deep[idx][nid] != 0);
        ans.push_back(idx);
        k -= deep[idx][nid];
        idx = nid;
    }
    assert(k == l);
    ans.push_back(idx);
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int l, n, k;
    cin >> l >> n >> k;
    vector<string> s(n);
    for (int i = 0; i < n; i++)
    {
        cin >> s[i];
    }
    if (1 || n > 1500)
        solve1(l, n, k, s);
    else
        solve2(l, n, k, s);
}

/*

5 3 10
abbab
babbb
aaaab

5 3 6
abbab
babbb
ddddd
*/
accuracy: 0.12903225806451613
time_ms: 680
memory_kb: 109960
final_rank: 20

code_snippet: #include <bits/stdc++.h>

using namespace std;

vector<int> z_func(string s)
{
    vector<int> z(s.size());
    int L = 0, R = 0;
    for (int i = 1; i < s.size(); i++)
    {
        z[i] = max(0, min(z[i - L], R - i));
        while (i + z[i] < s.size() && s[i + z[i]] == s[z[i]])
            z[i]++;
        if (i + z[i] > R)
        {
            R = i + z[i];
            L = i;
        }
    }
    return z;
}

void solve1(int l, int n, int k, vector<string> s)
{
    const int MOD = 1e9 + 239;
    const int BASE = 1e6 + 3;

    vector<int> deg(l + 1);
    deg[0] = 1;
    for (int i = 1; i <= l; i++) deg[i] = 1ll * deg[i - 1] * BASE % MOD;

    vector<vector<int> > pref_hash(n, vector<int>(l));
    vector<vector<int> > suff_hash(n, vector<int>(l));

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < l; j++)
        {
            if (j) pref_hash[i][j] = 1ll * pref_hash[i][j - 1] * BASE % MOD;
            pref_hash[i][j] = (pref_hash[i][j] + s[i][j]) % MOD;
        }
        for (int j = l - 1; j >= 0; j--)
        {
            if (j + 1 < l) suff_hash[i][j] = suff_hash[i][j + 1];
            suff_hash[i][j] = (suff_hash[i][j] + 1ll * s[i][j] * deg[l - 1 - j]) % MOD;
        }
    }

    vector<vector<int> > dp(k + 1, vector<int>(n, n));
    vector<vector<map<int, int> > > possible(k + 1, vector<map<int, int> >(l + 1));
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            int h = 0;
            for (int inter = 0; inter < l; inter++)
            {
                int olen = len - (l - inter);
                if (possible[olen][inter].find(h) != possible[olen][inter].end())
                {
                    dp[len][i] = min(dp[len][i], possible[olen][inter][h]);
                }
                h = (h + 1ll * s[i][l - 1 - inter] * deg[inter]) % MOD;
            }
            if (dp[len][i])
            {
                h = 0;
                for (int j = 0; j < l; j++)
                {
                    if (possible[len][j].find(h) == possible[len][j].end())
                        possible[len][j][h] = i;
                    h = (1ll * h * BASE + s[i][j]) % MOD;
                }
            }
        }
    }
    vector<vector<vector<int> > > paths(k + 1, vector<vector<int> >(n));
    for (int i = 0; i < n; i++)
        paths[l][i].push_back(i);

    for (int len = l + 1; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            if (dp[len][i] == n) continue;
            int j = dp[len][i];
            paths[len][i].push_back(i);
            vector<int> res = {n};
            if (dp[len - l][j] != n) res = paths[len - l][j];
            for (int inter = 1; inter < l; inter++)
            {
                if (suff_hash[i][l - inter] == pref_hash[j][inter - 1] &&
                    dp[len - l + inter][j] != n)
                {
                    res = min(res, paths[len - l + inter][j]);
                }
            }
            assert(res[0] != n);
            for (auto e : res) paths[len][i].push_back(e);
        }
    }

    vector<int> ans;
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] != n)
        {
            ans = paths[k][i];
            break;
        }
    }
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

void solve2(int l, int n, int k, vector<string> s)
{
    vector<vector<int> > dp(k + 1, vector<int>(n));
    vector<vector<int> > deep(n + 1, vector<int>(n + 1));
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            string ss = s[i] + s[j];
            vector<int> z = z_func(ss);
            deep[j][i] = l;
            for (int k = l + 1; k < 2 * l; k++)
            {
                if (k + z[k] == 2 * l)
                {
                    deep[j][i] = k - l;
                    break;
                }
            }
        }
    }
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < n; i++)
            {
                int nlen = len + deep[i][j];
                if (nlen <= k && dp[len][j] && !dp[nlen][i])
                {
                    dp[nlen][i] = 1;
                }
            }
        }
    }
    int idx = -1;
    string res = "";
    res += (char)('z' + 1);
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] && s[i] < res)
        {
            res = s[i];
            idx = i;
            break;
        }
    }
    assert(idx != -1);
    vector<int> ans;
    while (k > l)
    {
        string q = "";
        q += (char)('z' + 1);
        int nid = -1;
        for (int i = 0; i < n; i++)
        {
            int adds = deep[idx][i];
            if (adds == 0 || !dp[k - deep[idx][i]][i]) continue;
            string y = "";
            for (int p = l - deep[idx][i]; p < l; p++)
                y += s[i][p];
            q = y;
            nid = i;
            break;
        }
        res += q;
        assert(nid != -1);
        assert(deep[idx][nid] != 0);
        ans.push_back(idx);
        k -= deep[idx][nid];
        idx = nid;
    }
    assert(k == l);
    ans.push_back(idx);
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int l, n, k;
    cin >> l >> n >> k;
    vector<string> s(n);
    for (int i = 0; i < n; i++)
    {
        cin >> s[i];
    }
    if (1 || n > 1500)
        solve1(l, n, k, s);
    else
        solve2(l, n, k, s);
}

/*

5 3 10
abbab
babbb
aaaab

5 3 6
abbab
babbb
ddddd
*/
accuracy: 0.12903225806451613
time_ms: 680
memory_kb: 109956
final_rank: 19

code_snippet: #include <bits/stdc++.h>

using namespace std;

vector<int> z_func(string s)
{
    vector<int> z(s.size());
    int L = 0, R = 0;
    for (int i = 1; i < s.size(); i++)
    {
        z[i] = max(0, min(z[i - L], R - i));
        while (i + z[i] < s.size() && s[i + z[i]] == s[z[i]])
            z[i]++;
        if (i + z[i] > R)
        {
            R = i + z[i];
            L = i;
        }
    }
    return z;
}

void solve1(int l, int n, int k, vector<string> s)
{
    const int MOD = 1e9 + 9;
    const int BASE = 1e6 + 3;

    vector<int> deg(l + 1);
    deg[0] = 1;
    for (int i = 1; i <= l; i++) deg[i] = 1ll * deg[i - 1] * BASE % MOD;

    vector<vector<int> > pref_hash(n, vector<int>(l));
    vector<vector<int> > suff_hash(n, vector<int>(l));

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < l; j++)
        {
            if (j) pref_hash[i][j] = 1ll * pref_hash[i][j - 1] * BASE % MOD;
            pref_hash[i][j] = (pref_hash[i][j] + s[i][j]) % MOD;
        }
        for (int j = l - 1; j >= 0; j--)
        {
            if (j + 1 < l) suff_hash[i][j] = suff_hash[i][j + 1];
            suff_hash[i][j] = (suff_hash[i][j] + 1ll * s[i][j] * deg[l - 1 - j]) % MOD;
        }
    }

    vector<vector<int> > dp(k + 1, vector<int>(n, n));
    vector<vector<map<int, int> > > possible(k + 1, vector<map<int, int> >(l + 1));
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            int h = 0;
            for (int inter = 0; inter < l; inter++)
            {
                int olen = len - (l - inter);
                if (possible[olen][inter].find(h) != possible[olen][inter].end())
                {
                    dp[len][i] = min(dp[len][i], possible[olen][inter][h]);
                }
                h = (h + 1ll * s[i][l - 1 - inter] * deg[inter]) % MOD;
            }
            if (dp[len][i])
            {
                h = 0;
                for (int j = 0; j < l; j++)
                {
                    if (possible[len][j].find(h) == possible[len][j].end())
                        possible[len][j][h] = i;
                    h = (1ll * h * BASE + s[i][j]) % MOD;
                }
            }
        }
    }
    vector<vector<vector<int> > > paths(k + 1, vector<vector<int> >(n));
    for (int i = 0; i < n; i++)
        paths[l][i].push_back(i);

    for (int len = l + 1; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            if (dp[len][i] == n) continue;
            int j = dp[len][i];
            paths[len][i].push_back(i);
            vector<int> res = {n};
            if (dp[len - l][j] != n) res = paths[len - l][j];
            for (int inter = 1; inter < l; inter++)
            {
                if (suff_hash[i][l - inter] == pref_hash[j][inter - 1] &&
                    dp[len - l + inter][j] != n)
                {
                    res = min(res, paths[len - l + inter][j]);
                }
            }
            for (auto e : res) paths[len][i].push_back(e);
        }
    }

    vector<int> ans;
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] != n)
        {
            ans = paths[k][i];
            break;
        }
    }
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

void solve2(int l, int n, int k, vector<string> s)
{
    vector<vector<int> > dp(k + 1, vector<int>(n));
    vector<vector<int> > deep(n + 1, vector<int>(n + 1));
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            string ss = s[i] + s[j];
            vector<int> z = z_func(ss);
            deep[j][i] = l;
            for (int k = l + 1; k < 2 * l; k++)
            {
                if (k + z[k] == 2 * l)
                {
                    deep[j][i] = k - l;
                    break;
                }
            }
        }
    }
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < n; i++)
            {
                int nlen = len + deep[i][j];
                if (nlen <= k && dp[len][j] && !dp[nlen][i])
                {
                    dp[nlen][i] = 1;
                }
            }
        }
    }
    int idx = -1;
    string res = "";
    res += (char)('z' + 1);
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] && s[i] < res)
        {
            res = s[i];
            idx = i;
            break;
        }
    }
    assert(idx != -1);
    vector<int> ans;
    while (k > l)
    {
        string q = "";
        q += (char)('z' + 1);
        int nid = -1;
        for (int i = 0; i < n; i++)
        {
            int adds = deep[idx][i];
            if (adds == 0 || !dp[k - deep[idx][i]][i]) continue;
            string y = "";
            for (int p = l - deep[idx][i]; p < l; p++)
                y += s[i][p];
            q = y;
            nid = i;
            break;
        }
        res += q;
        assert(nid != -1);
        assert(deep[idx][nid] != 0);
        ans.push_back(idx);
        k -= deep[idx][nid];
        idx = nid;
    }
    assert(k == l);
    ans.push_back(idx);
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int l, n, k;
    cin >> l >> n >> k;
    vector<string> s(n);
    for (int i = 0; i < n; i++)
    {
        cin >> s[i];
    }
    if (1 || n > 1500)
        solve1(l, n, k, s);
    else
        solve2(l, n, k, s);
}

/*

5 3 10
abbab
babbb
aaaab

5 3 6
abbab
babbb
ddddd
*/
accuracy: 0.3387096774193548
time_ms: 1200
memory_kb: 395796
final_rank: 18

code_snippet: #include <bits/stdc++.h>

using namespace std;

vector<int> z_func(string s)
{
    vector<int> z(s.size());
    int L = 0, R = 0;
    for (int i = 1; i < s.size(); i++)
    {
        z[i] = max(0, min(z[i - L], R - i));
        while (i + z[i] < s.size() && s[i + z[i]] == s[z[i]])
            z[i]++;
        if (i + z[i] > R)
        {
            R = i + z[i];
            L = i;
        }
    }
    return z;
}

void solve1(int l, int n, int k, vector<string> s)
{
    const int MOD = 1e9 + 239;
    const int BASE = 1e6 + 3;

    vector<int> deg(l + 1);
    deg[0] = 1;
    for (int i = 1; i <= l; i++) deg[i] = 1ll * deg[i - 1] * BASE % MOD;

    vector<vector<int> > pref_hash(n, vector<int>(l));
    vector<vector<int> > suff_hash(n, vector<int>(l));

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < l; j++)
        {
            if (j) pref_hash[i][j] = 1ll * pref_hash[i][j - 1] * BASE % MOD;
            pref_hash[i][j] = (pref_hash[i][j] + s[i][j]) % MOD;
        }
        for (int j = l - 1; j >= 0; j--)
        {
            if (j + 1 < l) suff_hash[i][j] = suff_hash[i][j + 1];
            suff_hash[i][j] = (suff_hash[i][j] + 1ll * s[i][j] * deg[l - 1 - j]) % MOD;
        }
    }

    vector<vector<int> > dp(k + 1, vector<int>(n, n));
    vector<vector<map<int, int> > > possible(k + 1, vector<map<int, int> >(l + 1));
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            int h = 0;
            for (int inter = 0; inter < l; inter++)
            {
                int olen = len - (l - inter);
                if (possible[olen][inter].find(h) != possible[olen][inter].end())
                {
                    dp[len][i] = min(dp[len][i], possible[olen][inter][h]);
                }
                h = (h + 1ll * s[i][l - 1 - inter] * deg[inter]) % MOD;
            }
            if (dp[len][i])
            {
                h = 0;
                for (int j = 0; j < l; j++)
                {
                    if (possible[len][j].find(h) == possible[len][j].end())
                        possible[len][j][h] = i;
                    h = (1ll * h * BASE + s[i][j]) % MOD;
                }
            }
        }
    }
    vector<vector<vector<int> > > paths(k + 1, vector<vector<int> >(n));
    for (int i = 0; i < n; i++)
        paths[l][i].push_back(i);

    for (int len = l + 1; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            if (dp[len][i] == n) continue;
            int j = dp[len][i];
            paths[len][i].push_back(i);
            vector<int> res = {n};
            if (dp[len - l][j] != n) res = paths[len - l][j];
            for (int inter = 1; inter < l; inter++)
            {
                if (suff_hash[i][l - inter] == pref_hash[j][inter - 1] &&
                    dp[len - l + inter][j] != n)
                {
                    res = min(res, paths[len - l + inter][j]);
                }
            }
            for (auto e : res) paths[len][i].push_back(e);
        }
    }

    vector<int> ans;
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] != n)
        {
            ans = paths[k][i];
            break;
        }
    }
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

void solve2(int l, int n, int k, vector<string> s)
{
    vector<vector<int> > dp(k + 1, vector<int>(n));
    vector<vector<int> > deep(n + 1, vector<int>(n + 1));
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            string ss = s[i] + s[j];
            vector<int> z = z_func(ss);
            deep[j][i] = l;
            for (int k = l + 1; k < 2 * l; k++)
            {
                if (k + z[k] == 2 * l)
                {
                    deep[j][i] = k - l;
                    break;
                }
            }
        }
    }
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < n; i++)
            {
                int nlen = len + deep[i][j];
                if (nlen <= k && dp[len][j] && !dp[nlen][i])
                {
                    dp[nlen][i] = 1;
                }
            }
        }
    }
    int idx = -1;
    string res = "";
    res += (char)('z' + 1);
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] && s[i] < res)
        {
            res = s[i];
            idx = i;
            break;
        }
    }
    assert(idx != -1);
    vector<int> ans;
    while (k > l)
    {
        string q = "";
        q += (char)('z' + 1);
        int nid = -1;
        for (int i = 0; i < n; i++)
        {
            int adds = deep[idx][i];
            if (adds == 0 || !dp[k - deep[idx][i]][i]) continue;
            string y = "";
            for (int p = l - deep[idx][i]; p < l; p++)
                y += s[i][p];
            q = y;
            nid = i;
            break;
        }
        res += q;
        assert(nid != -1);
        assert(deep[idx][nid] != 0);
        ans.push_back(idx);
        k -= deep[idx][nid];
        idx = nid;
    }
    assert(k == l);
    ans.push_back(idx);
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int l, n, k;
    cin >> l >> n >> k;
    vector<string> s(n);
    for (int i = 0; i < n; i++)
    {
        cin >> s[i];
    }
    if (1 || n > 1500)
        solve1(l, n, k, s);
    else
        solve2(l, n, k, s);
}

/*

5 3 10
abbab
babbb
aaaab

5 3 6
abbab
babbb
ddddd
*/
accuracy: 0.3387096774193548
time_ms: 1180
memory_kb: 395832
final_rank: 17

code_snippet: #include <bits/stdc++.h>

using namespace std;

vector<int> z_func(string s)
{
    vector<int> z(s.size());
    int L = 0, R = 0;
    for (int i = 1; i < s.size(); i++)
    {
        z[i] = max(0, min(z[i - L], R - i));
        while (i + z[i] < s.size() && s[i + z[i]] == s[z[i]])
            z[i]++;
        if (i + z[i] > R)
        {
            R = i + z[i];
            L = i;
        }
    }
    return z;
}

void solve1(int l, int n, int k, vector<string> s)
{
    const int MOD = 1e9 + 239;
    const int BASE = 1e6 + 3;

    vector<int> deg(l + 1);
    deg[0] = 1;
    for (int i = 1; i <= l; i++) deg[i] = 1ll * deg[i - 1] * BASE % MOD;

    vector<vector<int> > dp(k + 1, vector<int>(n));
    vector<vector<map<int, int> > > possible(k + 1, vector<map<int, int> >(l + 1));
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            int h = 0;
            for (int inter = 0; dp[len][i] == 0 && inter < l; inter++)
            {
                int olen = len - (l - inter);
                if (possible[olen][inter].find(h) != possible[olen][inter].end())
                {
                    dp[len][i] = 1;
                }
                h = (h + 1ll * s[i][l - 1 - inter] * deg[inter]) % MOD;
            }
            if (dp[len][i])
            {
                h = 0;
                for (int j = 0; j < l; j++)
                {
                    if (possible[len][j].find(h) == possible[len][j].end())
                        possible[len][j][h] = i;
                    h = (1ll * h * BASE + s[i][j]) % MOD;
                }
            }
        }
    }
    vector<int> ans;
    int idx = -1;
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i])
        {
            idx = i;
            break;
        }
    }
    assert(idx != -1);
    ans.push_back(idx);

    while (k > l)
    {
        int back_hash = 0;
        int nidx = n, nlen = 0;
        for (int inter = 0; inter < l; inter++)
        {
            if (possible[k - l + inter][inter].find(back_hash) != possible[k - l + inter][inter].end())
            {
                int val = possible[k - l + inter][inter][back_hash];
                if (val < nidx)
                {
                    nidx = val;
                    nlen = k - l + inter;
                }
                assert(val != nidx);
            }
            back_hash = (back_hash + 1ll * s[idx][l - 1 - inter] * deg[inter]) % MOD;
        }
        assert(nidx != n);
        idx = nidx;
        k = nlen;
        ans.push_back(idx);
    }

    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

void solve2(int l, int n, int k, vector<string> s)
{
    vector<vector<int> > dp(k + 1, vector<int>(n));
    vector<vector<int> > deep(n + 1, vector<int>(n + 1));
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            string ss = s[i] + s[j];
            vector<int> z = z_func(ss);
            deep[j][i] = l;
            for (int k = l + 1; k < 2 * l; k++)
            {
                if (k + z[k] == 2 * l)
                {
                    deep[j][i] = k - l;
                    break;
                }
            }
        }
    }
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < n; i++)
            {
                int nlen = len + deep[i][j];
                if (nlen <= k && dp[len][j] && !dp[nlen][i])
                {
                    dp[nlen][i] = 1;
                }
            }
        }
    }
    int idx = -1;
    string res = "";
    res += (char)('z' + 1);
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] && s[i] < res)
        {
            res = s[i];
            idx = i;
            break;
        }
    }
    assert(idx != -1);
    vector<int> ans;
    while (k > l)
    {
        string q = "";
        q += (char)('z' + 1);
        int nid = -1;
        for (int i = 0; i < n; i++)
        {
            int adds = deep[idx][i];
            if (adds == 0 || !dp[k - deep[idx][i]][i]) continue;
            string y = "";
            for (int p = l - deep[idx][i]; p < l; p++)
                y += s[i][p];
            q = y;
            nid = i;
            break;
        }
        res += q;
        assert(nid != -1);
        assert(deep[idx][nid] != 0);
        ans.push_back(idx);
        k -= deep[idx][nid];
        idx = nid;
    }
    assert(k == l);
    ans.push_back(idx);
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int l, n, k;
    cin >> l >> n >> k;
    vector<string> s(n);
    for (int i = 0; i < n; i++)
    {
        cin >> s[i];
    }
    if (n > 1500)
        solve1(l, n, k, s);
    else
        solve2(l, n, k, s);
}

/*

5 3 10
abbab
babbb
aaaab

5 3 6
abbab
babbb
ddddd
*/
accuracy: 0.3548387096774194
time_ms: 210
memory_kb: 4676
final_rank: 14

code_snippet: #include <bits/stdc++.h>

using namespace std;

vector<int> z_func(string s)
{
    vector<int> z(s.size());
    int L = 0, R = 0;
    for (int i = 1; i < s.size(); i++)
    {
        z[i] = max(0, min(z[i - L], R - i));
        while (i + z[i] < s.size() && s[i + z[i]] == s[z[i]])
            z[i]++;
        if (i + z[i] > R)
        {
            R = i + z[i];
            L = i;
        }
    }
    return z;
}

void solve1(int l, int n, int k, vector<string> s)
{
    const int MOD = 1e9 + 239;
    const int BASE = 1e6 + 3;

    vector<int> deg(l + 1);
    deg[0] = 1;
    for (int i = 1; i <= l; i++) deg[i] = 1ll * deg[i - 1] * BASE % MOD;

    vector<vector<int> > dp(k + 1, vector<int>(n));
    vector<vector<map<int, int> > > possible(k + 1, vector<map<int, int> >(l + 1));
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            int h = 0;
            for (int inter = 0; dp[len][i] == 0 && inter < l; inter++)
            {
                int olen = len - (l - inter);
                if (possible[olen][inter].find(h) != possible[olen][inter].end())
                {
                    dp[len][i] = 1;
                }
                h = (h + 1ll * s[i][l - 1 - inter] * deg[inter]) % MOD;
            }
            if (dp[len][i])
            {
                h = 0;
                for (int j = 0; j < l; j++)
                {
                    if (possible[len][j].find(h) == possible[len][j].end())
                        possible[len][j][h] = i;
                    h = (1ll * h * BASE + s[i][j]) % MOD;
                }
            }
        }
    }
    vector<int> ans;
    int idx = -1;
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i])
        {
            idx = i;
            break;
        }
    }
    assert(idx != -1);
    ans.push_back(idx);

    while (k > l)
    {
        int back_hash = 0;
        int nidx = n, nlen = 0;
        for (int inter = 0; inter < l; inter++)
        {
            if (possible[k - l + inter][inter].find(back_hash) != possible[k - l + inter][inter].end())
            {
                int val = possible[k - l + inter][inter][back_hash];
                if (val < nidx)
                {
                    nidx = val;
                    nlen = k - l + inter;
                }
            }
            back_hash = (back_hash + 1ll * s[idx][l - 1 - inter] * deg[inter]) % MOD;
        }
        assert(nidx != n);
        idx = nidx;
        k = nlen;
        ans.push_back(idx);
    }

    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

void solve2(int l, int n, int k, vector<string> s)
{
    vector<vector<int> > dp(k + 1, vector<int>(n));
    vector<vector<int> > deep(n + 1, vector<int>(n + 1));
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            string ss = s[i] + s[j];
            vector<int> z = z_func(ss);
            deep[j][i] = l;
            for (int k = l + 1; k < 2 * l; k++)
            {
                if (k + z[k] == 2 * l)
                {
                    deep[j][i] = k - l;
                    break;
                }
            }
        }
    }
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < n; i++)
            {
                int nlen = len + deep[i][j];
                if (nlen <= k && dp[len][j] && !dp[nlen][i])
                {
                    dp[nlen][i] = 1;
                }
            }
        }
    }
    int idx = -1;
    string res = "";
    res += (char)('z' + 1);
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] && s[i] < res)
        {
            res = s[i];
            idx = i;
            break;
        }
    }
    assert(idx != -1);
    vector<int> ans;
    while (k > l)
    {
        string q = "";
        q += (char)('z' + 1);
        int nid = -1;
        for (int i = 0; i < n; i++)
        {
            int adds = deep[idx][i];
            if (adds == 0 || !dp[k - deep[idx][i]][i]) continue;
            string y = "";
            for (int p = l - deep[idx][i]; p < l; p++)
                y += s[i][p];
            q = y;
            nid = i;
            break;
        }
        res += q;
        assert(nid != -1);
        assert(deep[idx][nid] != 0);
        ans.push_back(idx);
        k -= deep[idx][nid];
        idx = nid;
    }
    assert(k == l);
    ans.push_back(idx);
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int l, n, k;
    cin >> l >> n >> k;
    vector<string> s(n);
    for (int i = 0; i < n; i++)
    {
        cin >> s[i];
    }
    if (n > 1500)
        solve1(l, n, k, s);
    else
        solve2(l, n, k, s);
}

/*

5 3 10
abbab
babbb
aaaab

5 3 6
abbab
babbb
ddddd
*/
accuracy: 0.3548387096774194
time_ms: 190
memory_kb: 4668
final_rank: 13

code_snippet: #include <bits/stdc++.h>

using namespace std;

vector<int> z_func(string s)
{
    vector<int> z(s.size());
    int L = 0, R = 0;
    for (int i = 1; i < s.size(); i++)
    {
        z[i] = max(0, min(z[i - L], R - i));
        while (i + z[i] < s.size() && s[i + z[i]] == s[z[i]])
            z[i]++;
        if (i + z[i] > R)
        {
            R = i + z[i];
            L = i;
        }
    }
    return z;
}

void solve1(int l, int n, int k, vector<string> s)
{
    const int MOD = 1e9 + 239;
    const int BASE = 1e6 + 3;

    vector<int> deg(l + 1);
    deg[0] = 1;
    for (int i = 1; i <= l; i++) deg[i] = 1ll * deg[i - 1] * BASE % MOD;

    vector<vector<int> > dp(k + 1, vector<int>(n));
    vector<vector<map<int, int> > > possible(k + 1, vector<map<int, int> >(l + 1));
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int i = 0; i < n; i++)
        {
            int h = 0;
            for (int inter = 0; dp[len][i] == 0 && inter < l; inter++)
            {
                int olen = len - (l - inter);
                if (possible[olen][inter].find(h) != possible[olen][inter].end())
                {
                    dp[len][i] = 1;
                }
                h = (h + 1ll * s[i][l - 1 - inter] * deg[inter]) % MOD;
            }
            if (dp[len][i])
            {
                h = 0;
                for (int j = 0; j < l; j++)
                {
                    if (possible[len][j].find(h) == possible[len][j].end())
                        possible[len][j][h] = i;
                    h = (1ll * h * BASE + s[i][j]) % MOD;
                }
            }
        }
    }
    vector<int> ans;
    int idx = -1;
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i])
        {
            idx = i;
            break;
        }
    }
    assert(idx != -1);
    ans.push_back(idx);

    while (k > l)
    {
        int back_hash = 0;
        int nidx = n, nlen = 0;
        for (int inter = 0; inter < l; inter++)
        {
            if (possible[k - l + inter][inter].find(back_hash) != possible[k - l + inter][inter].end())
            {
                int val = possible[k - l + inter][inter][back_hash];
                if (val < nidx)
                {
                    nidx = val;
                    nlen = k - l + inter;
                }
            }
            back_hash = (back_hash + 1ll * s[idx][l - 1 - inter] * deg[inter]) % MOD;
        }
        assert(nidx != n);
        idx = nidx;
        k = nlen;
        ans.push_back(idx);
    }

    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

void solve2(int l, int n, int k, vector<string> s)
{
    vector<vector<int> > dp(k + 1, vector<int>(n));
    vector<vector<int> > deep(n + 1, vector<int>(n + 1));
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            string ss = s[i] + s[j];
            vector<int> z = z_func(ss);
            deep[j][i] = l;
            for (int k = l + 1; k < 2 * l; k++)
            {
                if (k + z[k] == 2 * l)
                {
                    deep[j][i] = k - l;
                    break;
                }
            }
        }
    }
    for (int i = 0; i < n; i++)
        dp[l][i] = 1;
    for (int len = l; len <= k; len++)
    {
        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < n; i++)
            {
                int nlen = len + deep[i][j];
                if (nlen <= k && dp[len][j] && !dp[nlen][i])
                {
                    dp[nlen][i] = 1;
                }
            }
        }
    }
    int idx = -1;
    string res = "";
    res += (char)('z' + 1);
    for (int i = 0; i < n; i++)
    {
        if (dp[k][i] && s[i] < res)
        {
            res = s[i];
            idx = i;
            break;
        }
    }
    assert(idx != -1);
    vector<int> ans;
    while (k > l)
    {
        string q = "";
        q += (char)('z' + 1);
        int nid = -1;
        for (int i = 0; i < n; i++)
        {
            int adds = deep[idx][i];
            if (adds == 0 || !dp[k - deep[idx][i]][i]) continue;
            string y = "";
            for (int p = l - deep[idx][i]; p < l; p++)
                y += s[i][p];
            q = y;
            nid = i;
            break;
        }
        res += q;
        assert(nid != -1);
        assert(deep[idx][nid] != 0);
        ans.push_back(idx);
        k -= deep[idx][nid];
        idx = nid;
    }
    assert(k == l);
    ans.push_back(idx);
    cout << ans.size() << "\n";
    for (auto e : ans)
        cout << e << " ";
    cout << "\n";
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int l, n, k;
    cin >> l >> n >> k;
    vector<string> s(n);
    for (int i = 0; i < n; i++)
    {
        cin >> s[i];
    }
    if (1 || n > 1500)
        solve1(l, n, k, s);
    else
        solve2(l, n, k, s);
}

/*

5 3 10
abbab
babbb
aaaab

5 3 6
abbab
babbb
ddddd
*/
accuracy: 0.3548387096774194
time_ms: 180
memory_kb: 87804
final_rank: 15