'''
key: 
Solutions:
Similar: 
T:
S:
'''
from typing import List
from collections import deque


class Vector2D:

    def __init__(self, v: List[List[int]]):
        self.m = deque([val for r in v for val in r])
        
    # O(1)
    def next(self) -> int:
        return self.m.popleft()
        
    # O(1)
    def hasNext(self) -> bool:
        return self.m
    
    
    # official solution; S: O(1); two pointers
    # N be the number of integers within the 2D Vector, and V be the \
    # number of inner vectors.
class Vector2D1:
    # T: O(1)
    def __init__(self, v: List[List[int]]):
        self.vector = v
        self.inner = 0 # pointer
        self.outer = 0 # pointer
    
    # T: O(V/N)
    # If the current outer and inner point to an integer, this method does nothing.
    # Otherwise, inner and outer are advanced until they point to an integer.
    # If there are no more integers, then outer will be equal to vector.length
    # when this method terminates.
    def advance_to_next(self):
        # While outer is still within the vector, but inner is over the 
        # end of the inner list pointed to by outer, we want to move
        # forward to the start of the next inner vector.
        while self.outer < len(self.vector) and \
            self.inner == len(self.vector[self.outer]):
            self.outer += 1
            self.inner = 0
        
    # T: O(V/N) or O(1)
    def next(self) -> int:
        # Ensure the position pointers are moved such they point to an integer,
        # or put outer = vector.length.
        self.advance_to_next()
        # Return current element and move inner so that is after the current
        # element.
        result = self.vector[self.outer][self.inner]
        self.inner += 1
        return result
        

    def hasNext(self) -> bool:
        # Ensure the position pointers are moved such they point to an integer,
        # or put outer = vector.length.
        self.advance_to_next()
        # If outer = vector.length then there are no integers left, otherwise
        # we've stopped at an integer and so there's an integer left.
        return self.outer < len(self.vector)


# Your Vector2D object will be instantiated and called as such:
# obj = Vector2D(v)
# param_1 = obj.next()
# param_2 = obj.hasNext()