#include<stdio.h>
#include<stdlib.h>
typedef struct N {
    int d;
    struct N *p, *n;
} N;

N *h;

void i(int d) {
    N *n = malloc(sizeof(N));
    n->d = d;
    n->n = 0;
    if (!h) {
        n->p = 0;
        h = n;
        return;
    }
    N *t = h;
    while (t->n) t = t->n;
    t->n = n;
    n->p = t;
}

void delete_rear() {
    if (!h) {
        puts("Empty");
        return;
    }
    if (!h->n) {
        free(h);
        h = 0;
        return;
    }
    N *t = h;
    while (t->n) t = t->n;
    t->p->n = 0;
    free(t);
}

void ip(int d, int p) {
    N *n = malloc(sizeof(N));
    n->d = d;
    if (p == 1) {
        n->p = 0;
        n->n = h;
        if (h) h->p = n;
        h = n;
        return;
    }
    N *t = h;
    for (int i = 1; i < p - 1 && t; i++) t = t->n;
    if (!t) {
        puts("Out of range");
        return;
    }
    n->n = t->n;
    n->p = t;
    if (t->n) t->n->p = n;
    t->n = n;
}

void dp(int p) {
    if (!h) {
        puts("Empty");
        return;
    }
    N *t = h;
    if (p == 1) {
        h = h->n;
        if (h) h->p = 0;
        free(t);
        return;
    }
    for (int i = 1; i < p && t; i++) t = t->n;
    if (!t) {
        puts("Out of range");
        return;
    }
    t->p->n = t->n;
    if (t->n) t->n->p = t->p;
    free(t);
}

void ia(int d, int k) {
    N *n = malloc(sizeof(N));
    n->d = d;
    N *t = h;
    while (t && t->d != k) t = t->n;
    if (!t) {
        puts("Not found");
        return;
    }
    n->n = t->n;
    n->p = t;
    if (t->n) t->n->p = n;
    t->n = n;
}

void ib(int d, int k) {
    N *n = malloc(sizeof(N));
    n->d = d;
    if (!h) {
        puts("Empty");
        return;
    }
    if (h->d == k) {
        n->n = h;
        n->p = 0;
        h->p = n;
        h = n;
        return;
    }
    N *t = h;
    while (t->n && t->n->d != k) t = t->n;
    if (!t->n) {
        puts("Not found");
        return;
    }
    n->n = t->n;
    n->p = t;
    t->n->p = n;
    t->n = n;
}

void t() {
    for (N *t = h; t; t = t->n) printf("%d ", t->d);
    puts("");
}

void r() {
    N *t = 0, *c = h;
    while (c) {
        t = c->p;
        c->p = c->n;
        c->n = t;
        c = c->p;
    }
    if (t) h = t->p;
}

int main() {
    int c, d, p, k;
    while (1) {
        puts("\n1.Insert rear\n2.Delete rear\n3.Insert position\n4.Delete position\n5.Insert after\n6.Insert before\n7.Traverse\n8.Reverse\n9.Exit");
        printf("Choice: ");
        scanf("%d", &c);
        switch (c) {
            case 1:
                printf("Data: ");
                scanf("%d", &d);
                i(d);
                break;
            case 2:
                delete_rear();
                break;
            case 3:
                printf("Data: ");
                scanf("%d", &d);
                printf("Position: ");
                scanf("%d", &p);
                ip(d, p);
                break;
            case 4:
                printf("Position: ");
                scanf("%d", &p);
                dp(p);
                break;
            case 5:
                printf("Data: ");
                scanf("%d", &d);
                printf("After: ");
                scanf("%d", &k);
                ia(d, k);
                break;
            case 6:
                printf("Data: ");
                scanf("%d", &d);
                printf("Before: ");
                scanf("%d", &k);
                ib(d, k);
                break;
            case 7:
                t();
                break;
            case 8:
                r();
                break;
            case 9:
                exit(0);
            default:
                puts("Invalid");
        }
    }
}
