O(1) time, O(1) space | Beats 100% even the editorial ! 
ApproachAfter getting a MLE (Memory Limit Exceeded), I just realized that we don't care about the grid at all. The problem is just we have a large pack of eleme
# Approach
After getting a MLE (Memory Limit Exceeded), I just realized that we don't care about the grid at all. The problem is just we have a large pack of elements and we want to get a random one at each step. 
So I choose the first element randomly and choose the other based on him. 

Why this works ?
In fact it doesn't and I am going to explain why.
Let labeled the m*n elements from 0 to m*n-1. 

The probability to get the j-th element at the step k is the same as the probability to get (j-k)%m*n-th element at the first step and this is 1/m*n. 
So at the the k-th step the probability to get j-th element is not   1/(m*n-k). This is a contradiction because at each step, all elements should be equally likely to be returned. 

Honestly I think that my solution beats every all others because the testcases are too weak! 

##### I just found a glitch in the matrix :)
# Complexity
- Time complexity: $$O(1)$$
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

- Space complexity:$$O(1)$$
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

# Code
```python3 []
class Solution:

    def __init__(self, m: int, n: int):
        self.start = random.randint(0,m*n-1)
        self.m = m
        self.n = n
        
    def flip(self) -> List[int]:
        n1 = (self.start+1) % (self.m*self.n)
        self.start += 1
        return [n1 // self.n, n1 % self.n]
        

    def reset(self) -> None:
        self.start = random.randint(0,self.m*self.n-1)

# Your Solution object will be instantiated and called as such:
# obj = Solution(m, n)
# param_1 = obj.flip()
# obj.reset()
```
['Math', 'Probability and Statistics', 'Python3']