
dicc::dicc() : _arrel(nullptr) {}

dicc::~dicc() {
  esborra_nodes(_arrel);
}

void dicc::esborra_nodes(node* t) {
  if (t != nullptr) {
    esborra_nodes(t->_pf);
    esborra_nodes(t->_sg);
    delete t;
  }
}

dicc::node::node(const char &c, node* pf, node* sg) :
  _c(c), _pf(pf), _sg(sg) {
}

typename dicc::node* dicc::insereix(node *t, nat i, const string &k) {
  if (t == nullptr) {
    t = new node(k[i]);
    try {
      if (i < k.length()-1) {
        t->_pf = insereix(t->_pf, i+1, k);
      }
    }
    catch (...) {
      delete t;
      throw;
    }
  } else {
    if (t->_c > k[i]) {
      t = new node(k[i], nullptr, t);
      try {
        if (i < k.length()-1) {
          t->_pf = insereix(t->_pf, i+1, k);
        }
      }
      catch (...) {
        delete t;
        throw;
      }
    }
    else if (t->_c < k[i]) {
      t->_sg = insereix(t->_sg, i, k);
    }
    else { // (t->_c == k[i])
      if (i < k.length()-1)
        t->_pf = insereix(t->_pf, i+1, k);
    }
  }
  return t;
}

void dicc::insereix (const string &k) {
  _arrel = insereix(_arrel, 0, k + '#'); // Símbol # és la marca de fi de clau
}

void dicc::print(node* t, ostream &os, string prefix) {
  if (t == nullptr) 
    os << ".";
  else {
    string prefix2;
    os << t->_c;
    prefix2 = prefix + "|";
    print(t->_sg, os, prefix2);
    os << "\n" << prefix;// << "\\_";
    prefix2 = prefix;// + "  ";
    print(t->_pf, os, prefix2);
  }
}

void dicc::print(ostream &os) const {
  print(_arrel, os, "");
  os << "\n";
}

int main() {
  string input;
  dicc d;
  cin >> input;
  while (input != "----------") {
    d.insereix(input);
    cin >> input;
  }
  d.print(cout);
  cout << "----------" << endl;

  while (cin >> input) {
    d.elimina(input);
  }
  d.print(cout);

  return 0;
}
