The issue here is a subtle bug.
You are using the same variables for two different purposes, and by reusing those same variable names, their values get changed in ways that you didn't want/expect.
rows refers to the total number of rows to count up to, but then later you use it as the loop variable that does the counting, so the rows variable gets set to 0, then 1, then 2, etc.
Same issue for the columns variable.
A good coding pattern to follow would be to use
numThings (plural) to refer to the number of things you're counting up to, and use
thing (singular) as the variable that actually does the counting.
for thing in range(numThings):