<|instruction|>
Solve the below problem. The solution should start with an abridged problem statement. Then key observations. Then full solution based on the observations. Then C++ and Python implementations with comments.

359. Pointers
Time limit per test: 0.25 second(s)
Memory limit: 65536 kilobytes
input: standard
output: standard



Pete learns dynamic pointers. In informatics tutorial he read about pointers in Pascal. Pointer is a special variable, containing address of some location in RAM. That location can contain value of a certain type. Pete declared four pointers pointing to memory cells with integer values in a following manner:

var a, b, c, d : ^integer;

Than he allocated memory with instruction new:

new(a); new(b); new(c); new(d);

and assigned zero values to memory cells, pointed by these pointers:

a^:=0; b^:=0; c^:=0; d^:=0;

Please note that a^ means accessing location of memory, pointed by the pointer. Notation a (without symbol "^") means accessing to the pointer itself. Pete uses four types of operators in his program:
pointer^:=constant, e.g. a^:=5. This operator puts value constant into the memory area pointed by pointer (compare fig. 1 and fig. 2);
pointer1^:=pointer2^, e.g. c^:=a^. This operator puts value from the memory area pointed by pointer2 to the memory area pointed by pointer1 (compare fig. 2 and fig. 3);
pointer1:=pointer2, e.g. b:=c. After execution of this operator pointer1 will point to the same memory area as pointer2 (compare fig. 3 and fig. 4);
writeln(pointer^), e.g. writeln(b^). Prints value from the memory area pointed by pointer^ (operator writeln(b^) will print 5 in our example).



Pete use digits 0 to 9 as constants, and letters a, b, c or d as pointer variables.

Input
The first line of the input file contains integer number N (1 ≤ N ≤ 30). N lines follow. Each of the following lines contains exactly one operator of one of four described types. Each operator finished with symbol ";" (semicolon). Input file contains no blanks. You may assume that before executing of this program pointers a, b, c, d were declared, the memory was allocated for them, and memory areas pointed by them were filled with 0.

Output
Print to the output file numbers that will be printed by Pete's program.

Example(s)
sample input
sample output
10 
writeln(a^); 
a^:=7; 
b^:=a^; 
writeln(b^); 
c:=a; 
c^:=5; 
writeln(a^); 
a:=b; 
writeln(a^); 
a^:=a^; 
0 
7 
5 
7 

sample input
sample output
3 
a:=b; 
b^:=3; 
writeln(a^); 
3

<|response|>
## 1) Abridged problem statement (concise)

You have four Pascal-like pointer variables `a, b, c, d`. Initially, each points to its own distinct integer memory cell, and all those cells contain `0`.

You are given `N (1..30)` statements (no spaces, each ends with `;`) of one of these types:

1. `x^:=k` where `k` is digit `0..9` (store constant into the cell pointed by `x`)
2. `x^:=y^` (copy value from cell pointed by `y` into cell pointed by `x`)
3. `x:=y` (make pointer `x` point to the same cell as `y`)
4. `writeln(x^)` (print the value in the cell pointed by `x`)

Simulate execution and output every printed number (each on its own line).

---

## 2) Key observations

- There are **two levels**:
  - **Pointers** (`a,b,c,d`) store *addresses* (which cell they point to).
  - **Cells** store integer values.
- Statement `x:=y` changes **where a pointer points** (aliasing).
- Statements with `^` (`x^:=...`, `writeln(x^)`) read/write the **cell value** that the pointer currently refers to.
- Because pointers can alias (point to the same cell), updating one cell may affect what another pointer “sees”.

So we must simulate:
- the current target cell for each pointer, and
- each cell’s current integer value.

---

## 3) Full solution approach

### Data model
Create 4 distinct “cells” initially holding `0`.  
Maintain a mapping `ptr['a'..'d'] -> cell`.

A “cell” can be:
- in C++: an `int*` pointing to dynamically allocated `int`, or
- in Python: a mutable object like a one-element list `[value]`.

### How to process statements
Each line has no spaces and ends with `;`.

1. Strip trailing `;`.
2. If line starts with `"writeln("`:
   - extract pointer letter inside `writeln(x^)`, output the value of the cell `ptr[x]`.
3. Else it must be an assignment containing `":="`:
   - split into `left` and `right`.
   - If `left` ends with `'^'`, it’s a **cell assignment**:
     - `x^:=k` → write constant into cell `ptr[x]`
     - `x^:=y^` → copy `value(ptr[y])` into `ptr[x]`
   - Otherwise it’s a **pointer assignment**:
     - `x:=y` → set `ptr[x] = ptr[y]` (aliasing)

### Complexity
`N ≤ 30`, so simulation is trivial:
- Time: `O(N)`
- Memory: `O(1)`

---

## 4) C++ implementation

```cpp
#include <bits/stdc++.h>

using namespace std;

template<typename T1, typename T2>
ostream& operator<<(ostream& out, const pair<T1, T2>& x) {
    return out << x.first << ' ' << x.second;
}

template<typename T1, typename T2>
istream& operator>>(istream& in, pair<T1, T2>& x) {
    return in >> x.first >> x.second;
}

template<typename T>
istream& operator>>(istream& in, vector<T>& a) {
    for(auto& x: a) {
        in >> x;
    }
    return in;
};

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& a) {
    for(auto x: a) {
        out << x << ' ';
    }
    return out;
};

int n;
vector<string> lines;

void read() {
    cin >> n;
    lines.resize(n);
    cin >> lines;
}

void solve() {
    // This turns out to just be an implementation problem, and particularly in
    // C++ we can just use pointers and directly implement this.
    int* pa = new int(0);
    int* pb = new int(0);
    int* pc = new int(0);
    int* pd = new int(0);

    for(int i = 0; i < n; i++) {
        string line = lines[i];

        if(!line.empty() && line.back() == ';') {
            line.pop_back();
        }

        if(line.substr(0, 8) == "writeln(") {
            string inside = line.substr(8, line.size() - 8);
            if(!inside.empty() && inside.back() == ')') {
                inside.pop_back();
            }
            if(inside.size() != 2 || inside[1] != '^') {
                continue;
            }
            char p = inside[0];
            int val;
            if(p == 'a') {
                val = *pa;
            } else if(p == 'b') {
                val = *pb;
            } else if(p == 'c') {
                val = *pc;
            } else if(p == 'd') {
                val = *pd;
            } else {
                continue;
            }

            cout << val << endl;
        } else {
            size_t pos = line.find(":=");
            if(pos == string::npos) {
                continue;
            }

            string left = line.substr(0, pos);
            string right = line.substr(pos + 2);

            if(left.back() == '^') {
                if(left.size() != 2 || left[1] != '^') {
                    continue;
                }
                char p1 = left[0];
                int* ptr1;
                if(p1 == 'a') {
                    ptr1 = pa;
                } else if(p1 == 'b') {
                    ptr1 = pb;
                } else if(p1 == 'c') {
                    ptr1 = pc;
                } else if(p1 == 'd') {
                    ptr1 = pd;
                } else {
                    continue;
                }

                if(isdigit(right[0]) && right.size() == 1) {
                    int val = right[0] - '0';
                    *ptr1 = val;
                } else {
                    if(right.size() != 2 || right[1] != '^') {
                        continue;
                    }
                    char p2 = right[0];
                    int val;
                    if(p2 == 'a') {
                        val = *pa;
                    } else if(p2 == 'b') {
                        val = *pb;
                    } else if(p2 == 'c') {
                        val = *pc;
                    } else if(p2 == 'd') {
                        val = *pd;
                    } else {
                        continue;
                    }

                    *ptr1 = val;
                }
            } else {
                if(left.size() != 1) {
                    continue;
                }
                char p1 = left[0];
                if(right.size() != 1) {
                    continue;
                }
                char p2 = right[0];

                int* newptr;
                if(p2 == 'a') {
                    newptr = pa;
                } else if(p2 == 'b') {
                    newptr = pb;
                } else if(p2 == 'c') {
                    newptr = pc;
                } else if(p2 == 'd') {
                    newptr = pd;
                } else {
                    continue;
                }

                if(p1 == 'a') {
                    pa = newptr;
                } else if(p1 == 'b') {
                    pb = newptr;
                } else if(p1 == 'c') {
                    pc = newptr;
                } else if(p1 == 'd') {
                    pd = newptr;
                }
            }
        }
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int T = 1;
    // cin >> T;
    for(int test = 1; test <= T; test++) {
        read();
        // cout << "Case #" << test << ": ";
        solve();
    }

    return 0;
}
```

---

## 5) Python implementation (detailed comments)

```python
import sys

def solve() -> None:
    data = sys.stdin.read().strip().split()
    n = int(data[0])
    lines = data[1:1 + n]

    # Each memory cell is represented by a one-element list [value].
    # Lists are mutable and can be shared => perfect for aliasing pointers.
    cell_a = [0]
    cell_b = [0]
    cell_c = [0]
    cell_d = [0]

    # ptr maps pointer variable name to the cell object it points to.
    ptr = {
        'a': cell_a,
        'b': cell_b,
        'c': cell_c,
        'd': cell_d,
    }

    out = []

    for s in lines:
        # Remove trailing ';'
        if s.endswith(';'):
            s = s[:-1]

        # Case: writeln(x^)
        if s.startswith("writeln("):
            # s is like "writeln(a^)"
            x = s[len("writeln(")]  # the letter right after '('
            out.append(str(ptr[x][0]))
            continue

        # Otherwise: assignment with ':='
        left, right = s.split(":=")

        if left.endswith('^'):
            # Cell assignment: x^ := ...
            x = left[0]

            if len(right) == 1 and right.isdigit():
                # x^ := k
                ptr[x][0] = int(right)
            else:
                # x^ := y^
                y = right[0]
                ptr[x][0] = ptr[y][0]
        else:
            # Pointer assignment: x := y (alias)
            x = left[0]
            y = right[0]
            ptr[x] = ptr[y]

    sys.stdout.write("\n".join(out))

if __name__ == "__main__":
    solve()
```
