This example shows both the syntax you where looking for, and also an example of how you should use std::vector without new/delete.
#include <iostream>
#include <vector>
#include <memory>
// using namespace std; <== teach yourself NOT to do this.
// https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice
void access_pointers_in_2d_vector()
{
    std::vector<std::vector<int>*> values; // don't call your variables main!
    for (int j = 0; j < 3; j++)
    {
        std::vector<int>* myvector = new std::vector<int>;
        values.push_back(myvector);
    }
    values[0]->push_back(1);
    values[0]->push_back(4);
    values[1]->push_back(6);
    values[1]->push_back(7);
    values[1]->push_back(8);
    values[2]->push_back(3);
    for (int j = 0; j < 3; j++)
    {
        for (uint32_t i = 0; i < values[j]->size(); i++)
        {
            //==================================================================
            // this is the syntax you're looking for
            // first dereference the pointer then use operator[] 
            std::cout << (*values[j])[i] << " ";
            //==================================================================
        }
        std::cout << "\n";
    }
    // don't forget to cleanup your memory!
    // if you typed new somewhere then there should
    // ALWAYS be a matching delete in your code too!
    for (int j = 0; j < 3; j++)
    {
        delete values[j]; // <<==== !!!!!!!
    }
}
// for dynamic memory managment new/delete aren't recommended anymore.
// use std::unique_pointer (or if your design really requires it std::shared_ptr)
void using_unique_pointer()
{
    // If you really need pointers, use std::unique_ptr
    // it will prevent you from introducing memory leaks
    const std::uint32_t size = 3ul;
    std::vector<std::unique_ptr<std::vector<int>>> values(size);
    for (auto& p : values)
    {
        p = std::make_unique<std::vector<int>>();
    }
    values[0]->push_back(1);
    values[0]->push_back(4);
    values[1]->push_back(6);
    values[1]->push_back(7);
    values[1]->push_back(8);
    values[2]->push_back(3);
  // output loop is same as for normal pointers.
   // no need to call delete, std::unique_ptr will do that for you
}
void without_pointers()
{
    // However your whole code in idiomatic c++ should look like this.
    // https://en.cppreference.com/w/cpp/container/vector/vector constructor (10)
    // https://en.cppreference.com/w/cpp/language/range-for these loops avoid bugs related to 
    // letting indices go out of bounds.
    std::cout << "\nusing (nested) initializer list and range based for loops : \n";
    std::vector<std::vector<int>> rows{ {1,4}, {6,7,8}, {3} };
    for (const auto& row : rows)
    {
        for (const auto& value : row)
        {
            std::cout << value << " ";
        }
        std::cout << "\n";
    }
}
int main()
{
    access_pointers_in_2d_vector();
    using_unique_pointer();
    without_pointers();
    return 0;
}