I have an error in my code. It's a class that works with persistent array, but I decided not to use fat-node approach (or simply to store each version as an independent array) and I rewrite my code with a path copying approach. The problem I have: when I print all my versions to console I still get the very last version. 

Here's my output:
Value at index 2: 3
Value at index 2 after update: 10
Value at index 2 in old array: 3
Number of versions: 2
Version 0: 1 2 10 4 5 // Here I expected: 1 2 3 4 5 because it must be the first version
Version 1: 1 2 10 4 5 
Old version array: 1 2 3 4 5 
New version array: 1 2 10 4 5 

My code:
#include <iostream>
#include <memory>
#include <vector>

class SegmentTree {
public:
    int value;
    std::shared_ptr<SegmentTree> Left, Right;

    SegmentTree(int val) : value(val), Left(nullptr), Right(nullptr) {}
    SegmentTree(std::shared_ptr<SegmentTree> left, std::shared_ptr<SegmentTree> right)
        : Left(left), Right(right) {}
};

class PersistentArray {
private:
    std::shared_ptr<SegmentTree> root;
    std::vector<std::shared_ptr<SegmentTree>> versions; // Хранение всех версий
    int size;

    void build(std::shared_ptr<SegmentTree>& V, int* a, int L, int R) {
        if (L == R) {
            V = std::make_shared<SegmentTree>(a[L]);
            return;
        }
        int Mid = (L + R) / 2;
        std::shared_ptr<SegmentTree> leftChild, rightChild;
        build(leftChild, a, L, Mid);
        build(rightChild, a, Mid + 1, R);
        V = std::make_shared<SegmentTree>(leftChild, rightChild);
    }

    std::shared_ptr<SegmentTree> Update(std::shared_ptr<SegmentTree> V, int L, int R, int pos, int value) {
        if (!V) return nullptr;

        if (L == R) {
            return std::make_shared<SegmentTree>(value);
        }

        int Mid = (L + R) / 2;

        if (pos <= Mid) {
            std::shared_ptr<SegmentTree> newLeft = Update(V->Left, L, Mid, pos, value);
            return std::make_shared<SegmentTree>(newLeft, V->Right);
        } else {
            std::shared_ptr<SegmentTree> newRight = Update(V->Right, Mid + 1, R, pos, value);
            return std::make_shared<SegmentTree>(V->Left, newRight);
        }
    }

    // Изменен метод Get на const
    int Get(std::shared_ptr<SegmentTree> V, int L, int R, int pos) const {
        if (!V) return 0;

        if (L == R) return V->value;

        int Mid = (L + R) / 2;

        if (pos <= Mid) {
            return Get(V->Left, L, Mid, pos);
        } else {
            return Get(V->Right, Mid + 1, R, pos);
        }
    }

    // Изменен fillArray на const
    void fillArray(std::shared_ptr<SegmentTree> V, int* array, int L, int R) const {
        if (!V) return;

        if (L == R) {
            array[L] = V->value;
            return;
        }

        int Mid = (L + R) / 2;
        fillArray(V->Left, array, L, Mid);
        fillArray(V->Right, array, Mid + 1, R);
    }

public:
    PersistentArray(int* array, int n) {
        size = n;
        build(root, array, 0, n - 1);
        versions.push_back(root);
    }

    std::shared_ptr<PersistentArray> Update(int pos, int value) {
        std::shared_ptr<PersistentArray> newArray = std::make_shared<PersistentArray>(*this);
        newArray->root = Update(newArray->root, 0, size - 1, pos, value);
        newArray->versions.push_back(newArray->root);
        return newArray;
    }

    int Get(int pos) const {
        return Get(root, 0, size - 1, pos);
    }

    int versionCount() const {
        return versions.size();
    }

    void printAllVersions() const {
        for (size_t i = 0; i < versions.size(); ++i) {
            std::cout << "Version " << i << ": ";
            for (int j = 0; j < size; ++j) {
                std::cout << Get(j) << " "; // Теперь можно вызывать Get, так как он const
            }
            std::cout << std::endl;
        }
    }

    std::vector<int> versionToArray(int versionIndex) const {
        std::vector<int> result(size);
        if (versionIndex < 0 || versionIndex >= versions.size()) {
            throw std::out_of_range("Version index is out of range");
        }
        fillArray(versions[versionIndex], result.data(), 0, size - 1);
        return result;
    }
};

int main() {
    int a[] = { 1, 2, 3, 4, 5 };
    int n = 5;

    // Создаём персистентный массив
    std::shared_ptr<PersistentArray> array = std::make_shared<PersistentArray>(a, n);

    // Получаем значение по индексу 2
    std::cout << "Value at index 2: " << array->Get(2) << std::endl; // Должно вывести 3

    // Создаем новую версию массива с обновленным значением по индексу 2
    std::shared_ptr<PersistentArray> newArray = array->Update(2, 10);

    // Получаем значение по индексу 2 в новой версии
    std::cout << "Value at index 2 after update: " << newArray->Get(2) << std::endl; // Должно вывести 10

    // Получаем значение в старой версии
    std::cout << "Value at index 2 in old array: " << array->Get(2) << std::endl; // Должно вывести 3

    // Получаем количество версий
    std::cout << "Number of versions: " << newArray->versionCount() << std::endl;

    // Выводим все версии
    newArray->printAllVersions();

    // Преобразуем версию 0 в массив и выводим его
    auto oldVersionArray = newArray->versionToArray(0);
    std::cout << "Old version array: ";
    for (int x : oldVersionArray) {
        std::cout << x << " ";
    }
    std::cout << std::endl;

    auto newVersionArray = newArray->versionToArray(1);
    std::cout << "New version array: ";
    for (int x : newVersionArray) {
        std::cout << x << " ";
    }
    std::cout << std::endl;

    return 0;
}