#include <stdio.h>
#include <stdlib.h>

#define NULL ((void *)0)

struct node {
    char data;
    struct node* next;
};

struct node* read() {
    char c;
    struct node *tail = NULL, *node;
    struct node *list = NULL;
    for (;;) {
        c = getchar();
        if (c == '\n') break;

        node = malloc(sizeof(struct node));
        node->data = c;
        node->next = NULL;

        if (tail == NULL) {
            list = tail = node;
        } else {
            tail->next = node;
            tail = node;
        }
    }
    return list;
}

void print(struct node* list) {
    struct node *node = list;
    while(node != NULL) {
        putchar(node->data);
        node = node->next;
    }
    putchar('\n');
}

void delete(struct node* list) {
    struct node * node = list, *rest = list;
    while(rest != NULL) {
        node = rest;
        rest = rest->next;
        free(node);
    }
}

void loop_invert(struct node** list_addr) {
    struct node *source_head = *list_addr, *dest_head = NULL, *temp;
    while (source_head != NULL) {
        temp = source_head->next;
        source_head->next = dest_head;
        dest_head = source_head;
        source_head = temp;
    }
    *list_addr = dest_head;
}

void recursive_invert(struct node** list_addr) {
    struct node *source_head = *list_addr;
    struct node *dest_tail = source_head->next;

    if (source_head->next == NULL) return;

    recursive_invert(&(source_head->next));

    *list_addr = source_head->next;
    dest_tail->next = source_head;
    dest_tail = source_head;
    dest_tail->next = NULL;
}

void _tail_recursive_invert(struct node** source_addr, struct node** dest_addr) {
    struct node *source_head = *source_addr,
            *dest_head = *dest_addr,
            *new_source_head;
    if (source_head == NULL) return;
    new_source_head = source_head->next;
    source_head->next = dest_head;
    *dest_addr = source_head;
    _tail_recursive_invert(&new_source_head, dest_addr);
}

void tail_recursive_invert(struct node** list_addr) {
    struct node **dest_addr = malloc(sizeof(struct node*));
    *dest_addr = NULL;
    _tail_recursive_invert(list_addr, dest_addr);
    *list_addr = *dest_addr;
    free(dest_addr);
}

int main() {
    struct node *list = read();
    loop_invert(&list);
    print(list);
    recursive_invert(&list);
    print(list);
    tail_recursive_invert(&list);
    print(list);
    delete(list);
    return EXIT_SUCCESS;
}