program collatz
implicit none

integer*8 :: i,n,count,begin

type :: seq
  integer*8 :: count, n
end type

type(seq) :: maxsequence=seq(0,0)

!$omp declare reduction (max: seq : maxseq(omp_out, omp_in)) &
!$omp& initializer( omp_priv=seq(0,0))

!write(*,*) 'Enter begin value'
!read(*,*) begin
begin=1000000


!$omp parallel do private(n,i,count) reduction(max:maxsequence)
do i=begin,1,-1
  n = i
  count = 1

  do while (n /= 1)
    if (mod(n,2) == 0) then
      n = n/2
    else
      n = 3*n+1
    end if
    count = count+1
  end do
!  write(*,*) i,count

  if (count > maxsequence%count) then
    maxsequence%count = count
    maxsequence%n = i
  end if
end do

write(*,'("Max Collatz sequence is for ",i7," and has length ",i4)') maxsequence%n, maxsequence%count

contains

  subroutine maxseq(out,in)
    implicit none
    type(seq), intent(inout) :: out
    type(seq), intent(in) :: in

    if (out%count < in%count) then
      out%count = in%count
      out%n = in%n
    end if
  end subroutine maxseq
end program    
