
For this, I think a better option than creating a grid directly, is to do this from columns and rows, this will allow you to create a logic and a linear hierarchy, so you don't need to enter loops and complex verifications to avoid intersections between rectangles and squares.

1. First let's create our columns:
for this use a Mesh Line, and set the offset with the size of your module, and add a group input to control the amount of columns.

2. Create the rows:
very similar process but now use the Offset in Y, with the same size and instance on the columns created previously

3. Now let's transform this into points
and assign an ID to them, this will be useful later on.

4. Let's create some attributes
that will be important for the behavior and rules of your grid.
4.1 - Create Horizontal Rectangles
and verify if equivalent point of previous column is an H-Rectangle, if so, we cannot use this point. Save all this as an attribute to be reused later.
For this, you can randomize a value where 0 would be a square and 1 would be a rectangle, using the random node in boolean mode, you can control a probability factor, after that just use a sample index with the value of Index - (Amount of objects per column) so that we always get the neighboring value from the left, and compare to know if it's 0 or 1. That is, if the left neighbor is 1, it means it will also occupy the space of this current point.

4.2 - Create an ID for each Column
this will be very important so we can move an entire column vertically later. To create this I just take the Index and use a modulo function using the number of objects per column and then divide by the same value, this will return a sequence corresponding to each column.

4.3 - Verify if in the column in question there is any rectangle,
this will be very important to prevent us from moving this column and causing overlaps. To make this verification I use the attribute created previously as a group ID, and use the Accumulate Field (Total) from the Hrectangles attribute that we also created previously, this will make it sum all the values of the column in question, if it's 0, it means there's no rectangle in it.

5. Instance the H-Rectangles
Just use an Instance on points and connect the output of your Random Value to the selection, so you only instance on points that are 1. Then let's create the squares.

6. Instance the squares and the Vertical Rectangles
Besides just instancing we'll need to make a similar logic to verify if a point is above a point that already received a rectangle and not use it. For this just use the same reasoning, but instead of subtracting by the number of objects that exist per row, just subtract by -1, this will make it check only one point behind (the one below).
Create a randomize also to define which points are squares and which are Vertical Rectangles.
Besides that, you'll also need to verify if it's not already a point that had a horizontal rectangle, because this would also create an overlap, just use the attribute we already created previously and subtract from your values.

7. Displace some columns
For this we just need to use a translate instance, with some randomized selection, let's again use a Random Node, but we'll use our ID per column as a group, so we get the same value for all points of each column.
After that, just set this offset by half the size of your module and it will make it align to the middle.

8. Finally, just join
with the horizontal rectangles. Using a joint geometry joining your 2 instances on points

Now, you can add other Random or Noises to create more empty spaces like your reference.