#include <iostream>
#include <cassert>
#include <vector>
#include <string>
using namespace std;

//#define DEBUG

#if defined(DEBUG)
#define debug(code) {code}
#else
#define debug(code)
#endif

#define ASSERT(condition, message) {                               \
    if(!(condition)) {                                             \
        cout << "Assertion Failed: " << message << endl;           \
        exit(EXIT_FAILURE);                                        \
    }                                                              \
}

class EmacsLikeEditor {
  private:
    // Text as a vector with one element per line
    vector<string> lines;
    // Position of cursor
    int row, col;
    string buffer;
    int getRowHead() { return 0; }
    int getRowEnd() { return lines.size() - 1; }
    int getColHead() { return 0; }
    int getColEnd() { return lines[row].length() - 1; }
  public:
    EmacsLikeEditor(vector<string> lines) {
      this->lines = lines;
      this->row = 0;
      this->col = 0;
      this->buffer = "";
    }
    // Print text content
    void printText() {
      for(string line : lines) {
        cout << line;
      }
    }
    // Move cursor to first character of current line
    void moveHeadOfLine() {
      col = getColHead();
      ASSERT(0 <= col && col < lines[row].length(), "Column number out of range");
    }
    // Move cursor to end-of-line of current line
    void moveEndOfLine() {
      col = getColEnd();
      ASSERT(0 <= col && col < lines[row].length(), "Column number out of range");
    }
    // Move cursor to first character of next upper line
    void movePrevLine() {
      // Do not move line if there is no line above
      if(row != getRowHead()) row -= 1;
      col = getColHead();
      ASSERT(0 <= row && row < lines.size(), "Line number out of range");
      ASSERT(0 <= col && col < lines[row].length(), "Column number out of range");
    }
    // Move cursor to first character of next lower line
    void moveNextLine() {
      // Do not move line if there is no line below
      if(row != getRowEnd()) row += 1;
      col = getColHead();
      ASSERT(0 <= row && row < lines.size(), "Line number out of range");
      ASSERT(0 <= col && col < lines[row].length(), "Column number out of range");
    }
    // Move cursor by one character to front
    void moveFront() {
      // If cursor does not points out end-of-line
      if(col != getColEnd()) {
        // Move cursor by one character to right
        col += 1;
      }
      // If cursor points out end-of-line and there is line below
      else if(row != getRowEnd()) {
        // Move cursor to first character of next lower line
        row += 1;
        col = getColHead();
      }
      ASSERT(0 <= row && row < lines.size(), "Line number out of range");
      ASSERT(0 <= col && col < lines[row].length(), "Column number out of range");
    }
    // Move cursor by one character to back
    void moveBack() {
      // If cursor does not points out first character
      if(col != getColHead()) {
        // Move cursor by one character to left
        col -= 1;
      }
      // If cursor points out first character and there is line above
      else if(row != getRowHead()) {
        // Move cursor to end-of-line of next upper line
        row -= 1;
        col = getColEnd();
      }
      ASSERT(0 <= row && row < lines.size(), "Line number out of range");
      ASSERT(0 <= col && col < lines[row].length(), "Column number out of range");
    }
    // Delete character
    void deleteChar() {
      string line = lines[row];
      // If cursor points out a character
      if(col != getColEnd()) {
        line.erase(line.begin() + col);
        lines[row] = line;
      }
      // If cursor points out end-of-line and there is line below
      else if(row != getRowEnd()) {
        // Next lower line is appended to end-of-line of current line
        int nextRow = row + 1;
        line.pop_back();
        line += lines[nextRow];
        lines[row] = line;
        lines.erase(lines.begin() + nextRow);
      }
      ASSERT(0 <= row && row < lines.size(), "Line number out of range");
      ASSERT(0 <= col && col < lines[row].length(), "Column number out of range");
    }
    // Cut characters between cursor and end-of-line, and record them on buffer
    void deleteRightAll() {
      string line = lines[row];
      // If cursor does not point out end-of-line
      if(col != getColEnd()) {
        // Record characters between cursor and end-of-line on buffer
        buffer = line.substr(col, getColEnd() - col);
        // Cut characters between cursor and end-of-line
        line.erase(line.begin() + col, line.begin() + line.length() - 1);
        lines[row] = line;
        // Cursor indicates end-of-line of current line
        col = getColEnd();
      }
      // If cursor points out end-of-line and there is line below
      else if(row != getRowEnd()) {
        // Record linefeed on buffer
        buffer = "\n";
        // Perform the command d
        deleteChar();
      }
      ASSERT(0 <= row && row < lines.size(), "Line number out of range");
      ASSERT(0 <= col && col < lines[row].length(), "Column number out of range");
    }
    void paste() {
      string line = lines[row];
      string formerText, latterText;
      formerText = line.substr(getColHead(), col);
      latterText = line.substr(col, line.length() - col);
      // If buffer is holding linefeed
      if(buffer == "\n") {
        // Insert linefeed at cursor
        lines[row] = formerText + buffer;
        lines.insert(lines.begin() + row + 1, latterText);
        // Cursor moves to first character of new line
        row += 1;
        col = getColHead();
      }
      // If buffer is holding characters
      else if(buffer != "") {
        // Insert the characters at cursor
        lines[row] = formerText + buffer + latterText;
        // Cursor moves to the character which is originally pointed by cursor
        col += buffer.length();
      }
      ASSERT(0 <= row && row < lines.size(), "Line number out of range");
      ASSERT(0 <= col && col < lines[row].length(), "Column number out of range");
    }
    // Trace text content for debugging
    void traceText() {
        debug(
            cout << endl;
            for(int i = 0; i < lines.size(); i++) {
                for(int j = 0; j < lines[i].length(); j++) {
                    // The character at cursor is enclosed in brackets
                    if(i == row && j == col) {
                        if(lines[i][j] == '\n') cout << "[]" << lines[i][j];
                        else cout << '[' << lines[i][j] << ']';
                    }
                    else {
                        cout << lines[i][j];
                    }
                }
            }
            cout << endl;
        );
    }
};

int main() {
    vector<string> inputLines;
    string inputLine;
    char command;

    // Read a text consisting of several lines
    while(1) {
      getline(cin, inputLine);
      if(inputLine == "END_OF_TEXT") break;
      inputLines.push_back(inputLine + '\n');
    }

    EmacsLikeEditor editor(inputLines);

    // Read a series of commands
    while(1) {
      getline(cin, inputLine);
      ASSERT(inputLine.length() == 1, "Command must be one character per line");
      command = inputLine[0];
      if(command == '-') break;
      switch(command) {
        case 'a':
          editor.moveHeadOfLine();
          break;
        case 'e':
          editor.moveEndOfLine();
          break;
        case 'p':
          editor.movePrevLine();
          break;
        case 'n':
          editor.moveNextLine();
          break;
        case 'f':
          editor.moveFront();
          break;
        case 'b':
          editor.moveBack();
          break;
        case 'd':
          editor.deleteChar();
          break;
        case 'k':
          editor.deleteRightAll();
          break;
        case 'y':
          editor.paste();
          break;
        default:
          break;
      }
      editor.traceText();
    }

    editor.printText();

    return 0;
}



Measured memory_bytes: 3144