    !-*- mode: compilation; default-directory: "/tmp/" -*-
    !Compilation started at Thu Jun  5 01:52:03
    !
    !make f && for a in '' a bark book treat common squad confuse ; do echo $a | ./f ; done
    !gfortran -std=f2008 -Wall -fopenmp -ffree-form -fall-intrinsics -fimplicit-none -g f.f08 -o f
    ! T
    ! T  A                    NA
    ! T  BARK                 BO NA RE XK
    ! F  BOOK                 OB BO -- --
    ! T  TREAT                GT RE ER NA TG
    ! F  COMMON               PC OB ZM -- -- --
    ! T  SQUAD                FS DQ HU NA QD
    ! T  CONFUSE              CP BO NA FS HU FS RE
    !
    !Compilation finished at Thu Jun  5 01:52:03

    program abc
      implicit none
      integer, parameter :: nblocks = 20
      character(len=nblocks) :: goal
      integer, dimension(nblocks) :: solution
      character(len=2), dimension(0:nblocks) :: blocks_copy, blocks = &
           &(/'--','BO','XK','DQ','CP','NA','GT','RE','TG','QD','FS','JW','HU','VI','AN','OB','ER','FS','LY','PC','ZM'/)
      logical :: valid
      integer :: i, iostat
      read(5,*,iostat=iostat) goal
      if (iostat .ne. 0) goal = ''
      call ucase(goal)
      solution = 0
      blocks_copy = blocks
      valid = assign_block(goal(1:len_trim(goal)), blocks, solution, 1)
      write(6,*) valid, ' '//goal, (' '//blocks_copy(solution(i)), i=1,len_trim(goal))

    contains

      recursive function assign_block(goal, blocks, solution, n) result(valid)
        implicit none
        logical :: valid
        character(len=*), intent(in) :: goal
        character(len=2), dimension(0:), intent(inout) :: blocks
        integer, dimension(:), intent(out) :: solution
        integer, intent(in) :: n
        integer :: i
        character(len=2) :: backing_store
        valid = .true.
        if (len(goal)+1 .eq. n) return
        do i=1, size(blocks)
           if (index(blocks(i),goal(n:n)) .ne. 0) then
              backing_store = blocks(i)
              blocks(i) = ''
              solution(n) = i
              if (assign_block(goal, blocks, solution, n+1)) return
              blocks(i) = backing_store
           end if
        end do
        valid = .false.
        return
      end function assign_block

      subroutine ucase(a)
        implicit none
        character(len=*), intent(inout) :: a
        integer :: i, j
        do i = 1, len_trim(a)
           j = index('abcdefghijklmnopqrstuvwxyz',a(i:i))
           if (j .ne. 0) a(i:i) = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'(j:j)
        end do
      end subroutine ucase

    end program abc