import java.util.Scanner;

class Node<T> {
    T data;
    Node<T> next;

    public Node(T data) {
        this.data = data;
        this.next = null;
    }
}

class GenericStackArray<T> {
    private T[] stackArray;
    private int top;
    private int maxSize;

    @SuppressWarnings("unchecked")
    public GenericStackArray(int size) {
        this.maxSize = size;
        this.stackArray = (T[]) new Object[maxSize];
        this.top = -1;
    }

    public void push(T item) {
        if (top < maxSize - 1) {
            stackArray[++top] = item;
        } else {
            System.out.println("Stack Overflow");
        }
    }

    public T pop() {
        if (top >= 0) {
            return stackArray[top--];
        } else {
            System.out.println("Stack Underflow");
            return null;
        }
    }
public T peek() {
        if (top == -1) {
            System.out.println("Stack is empty.");
            return null;
        } else {
            return stackArray[top];
        }
    }

    public boolean isEmpty() {
        return top == -1;
    }
}

class GenericStackLinkedList<T> {
    private Node<T> top;

    public GenericStackLinkedList() {
        this.top = null;
    }

    public void push(T item) {
        Node<T> newNode = new Node<>(item);
        newNode.next = top;
        top = newNode;
    }

    public T pop() {
        if (top == null) {
            System.out.println("Stack Underflow");
            return null;
        }
        T data = top.data;
        top = top.next;
        return data;
    }
public T peek() {
        if (top == null) {
            System.out.println("Stack is empty.");
            return null;
        } else {
            return top.data;
        }
    }
    public boolean isEmpty() {
        return top == null;
    }
}

public class Main{
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("ARRAY....");
        GenericStackArray<Integer> intArrayStack = new GenericStackArray<>(10);
        intArrayStack.push(1);
        intArrayStack.push(2);
        System.out.println(intArrayStack.pop());  // Output: 2
        System.out.println(intArrayStack.peek()); // Output: 1

        GenericStackArray<Double> doubleArrayStack = new GenericStackArray<>(10);
        doubleArrayStack.push(1.1);
        doubleArrayStack.push(2.2);
        System.out.println(doubleArrayStack.pop());  // Output: 2.2
        System.out.println(doubleArrayStack.peek()); // Output: 1.1

        GenericStackArray<String> stringArrayStack = new GenericStackArray<>(10);
        stringArrayStack.push("Hello");
        stringArrayStack.push("World");
        System.out.println(stringArrayStack.pop());  // Output: World
        System.out.println(stringArrayStack.peek()); // Output: Hello

System.out.println("\nLINKED LIST....");
        // Linked list-based stack
        GenericStackLinkedList<Integer> intLinkedListStack = new GenericStackLinkedList<>();
        intLinkedListStack.push(1);
        intLinkedListStack.push(2);
        System.out.println(intLinkedListStack.pop());  // Output: 2
        System.out.println(intLinkedListStack.peek()); // Output: 1

        GenericStackLinkedList<Double> doubleLinkedListStack = new GenericStackLinkedList<>();
        doubleLinkedListStack.push(1.1);
        doubleLinkedListStack.push(2.2);
        System.out.println(doubleLinkedListStack.pop());  // Output: 2.2
        System.out.println(doubleLinkedListStack.peek()); // Output: 1.1

        GenericStackLinkedList<String> stringLinkedListStack = new GenericStackLinkedList<>();
        stringLinkedListStack.push("Hello");
        stringLinkedListStack.push("World");
        System.out.println(stringLinkedListStack.pop());  // Output: World
        System.out.println(stringLinkedListStack.peek()); // Output: Hello
}
}