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

class Trie {
private:
    static const int chars = 26;
    Trie* child[chars];
    bool isLeaf{};

public:
    vector<string>allwords;
    Trie() {
        memset(child, 0, sizeof(child));
    }
    ~Trie() {
        for (int i = 0; i < chars; i++) {
            if (child[i]) {
                delete child[i];
            }
        }
    }
    //Problem 1 : a
    void insert(string s) {
        Trie* current = this;
        for (char c : s) {
            int index = c - 'a';
            if (!current->child[index]) {
                current->child[index] = new Trie();
            }
            current = current->child[index];
        }
        allwords.push_back(s);
        current->isLeaf = true;
    }
    //Problem 1 : b
    bool word_exists(string s) {
        Trie* current = this;
        for (char c : s) {
            int index = c - 'a';
            if (!current->child[index]) {
                return false;
            }
            current = current->child[index];
        }
        return current->isLeaf;
    }
    //Problem 2 : minimal prefix
    string first_word_prefix(const string &str){
        vector<string>all;
        Trie* current = this;
        string prefix = "";
        for (char c : str) {
            int index = c - 'a';
            if (!current->child[index]) break; 
            prefix += c;
            current = current->child[index];
            if (current->isLeaf) all.push_back(prefix);
        }
        if(all.empty()){
            return str;
        }
        return *min_element(all.begin(), all.end());
    }
    //Problem 3 : Is suffix
    void SuffixExists(const string& s) {
        for(auto word : allwords){
            vector<string>allsuffixes;
            for(int i = 0; i <(int) word.size(); i++){
                allsuffixes.push_back(word.substr(i));
            }
            for(auto w: allsuffixes){
                if(w == s){
                    cout << "yes it is found \n";
                    return;
                }
            }
        }
        cout << "No suffix found" << endl;
    }
};

//Problem 4 and 5:
class Trie3 {
private:
    //static const int size =256;
    unordered_map<string, Trie3*> child;
    bool isLeaf;

public:
    Trie3() : isLeaf(false) {}

    ~Trie3() {
        for (auto &entry : child) {
            delete entry.second;
        }
    }

    void insert(const vector<string>& path) {
        Trie3* current = this;
        for (const auto& word : path) {
            if (current->child.find(word) == current->child.end()) {
                current->child[word] = new Trie3();
            }
            current = current->child[word];
        }
        current->isLeaf = true; 
    }

    bool subpath_exists(const vector<string>& path) {
        Trie3* current = this;
        for (const auto& word : path) {
            if (current->child.find(word) == current->child.end()) {
                //first change than insert
                return false;
            }
            current = current->child[word];
        }
        //second change than insert
        return true;  
    }
};
int main() {
    string s;cin >> s;
    Trie trie;
    trie.insert("hello");
    trie.insert("manar");
    trie.insert("man");
    trie.insert("elhabbal");
    trie.insert("xyz");
    trie.insert("xyzea");
    trie.insert("a");
    trie.insert("bc");

    trie.SuffixExists("habbal");
    trie.SuffixExists("nar");
    trie.SuffixExists("lo");
    trie.SuffixExists("gold");
    cout <<"--------------------------------\n";
    cout << trie.first_word_prefix("x")<<endl;
    cout << trie.first_word_prefix("xyzabc")<<endl;
    cout << trie.first_word_prefix("manarelhabbal")<<endl;
    cout <<"--------------------------------\n";
    Trie3 trie3;
    vector<string> path1 = {"home","software","eclipse"};
    vector<string> path2 = {"home","software","eclipse","bin"};
    vector<string> path3 = {"home","installed","gnu"};
    vector<string> path4 = {"user","mostafa","temp"};
    trie3.insert(path1);
    trie3.insert(path2);
    trie3.insert(path3);
    trie3.insert(path4);
    vector<string>f1={"user","mostafa","temp"};
    vector<string>f2={"user","mostafa"};
    vector<string>f3={"user","mos"};
    vector<string>f4={"user","mostafa","private"};
    cout << trie3.subpath_exists(f1) << endl;
    cout << trie3.subpath_exists(f2) << endl;
    cout << trie3.subpath_exists(f3) << endl;
    cout << trie3.subpath_exists(f4) << endl;
    cout <<"--------------------------------\n";
    return 0;
}
