More effort needed in parsing and initialising for the fft convolution approach - all this is setup in the "Init" function - but the core logic is pretty dense (and I think could be denser as I get better at using subscripted on/by instead of forks with different selectors to preserve values - Convolve can probably be shorter before the first fft).
If you remove one of the "gaps" at the left of the final line and replace it with an &ims you get a nice b/w image of the final state. (and you can modify the internal loop with a suitabley surrounded ⟜&ims to display the intermediate states if you want).
(This is pt2 - for pt1 most of the same logic applies, but you can just do the bits inside the loop without needing the loop [and the handling is simpler because you don't need to accumulate after the functions])
Parse ← ≡₀°□=@@⊜□⊸≠@\n &fras
Kernel ← [1_1_1 1_0_1 1_1_1]
Pad ← ↻⊙∩⌞(⬚0↙)∩(˙⊂)◡(⌊÷₂⟜(-₁+)∩⧻)
Init ← 1 Pad Kernel Parse⟜(0)
Convolve ← ⌵⁅×°fft×∩fft⊃(⊙⋅)(⟜⧻⋅∘)
Mask ← ⊸₂(×⊙⋅∘)<4
Apply ← /+/+⟜₂(⍜⊡(×0)⊚ ⊙◌)
Accum ← ⟜₃(+⊙⋅⋅∘)
⋅⋅⋅∘⍢(Accum Apply Mask ◡Convolve◌|≠0) Init "input"