```
def smallestRange(self, A):
A = [row[::-1] for row in A]
ans = -1e9, 1e9
for left in sorted(reduce(set.union, map(set, A))):
right = -1e9
for B in A:
while B and B[-1] < left:
B.pop()
if not B:
return ans
right = max(right, B[-1])
if right - left < ans[1] - ans[0]:
ans = left, right
return ans
```

Clearly, each left and right bound must be a value in some array.

For each candidate left bound equal to some value in some array, let's determine the next-rightmost value of each array. If it doesn't exist, then our left is already too large for any subsequent candidates to have a solution. Otherwise, we can choose the maximum of these to be the corresponding right bound for our candidate left bound. We take the maximum of all such candidates.