FUNCTION is_mersenne(k)
  IMPLICIT NONE
  INTEGER, INTENT (in) :: k
  LOGICAL :: is_mersenne
  INTEGER :: n

  is_mersenne = .TRUE.

  n = k + 1
  DO 
     IF (n == 2) EXIT

     IF (MOD(n,2) /= 0) THEN
        is_mersenne = .FALSE.
        EXIT
     END IF

     n = n / 2
  END DO

END FUNCTION is_mersenne


FUNCTION is_prime(k)
  IMPLICIT NONE
  INTEGER, INTENT (in) :: k
  LOGICAL :: is_prime

  INTEGER :: i

  is_prime = .TRUE.  
  DO i=2,k-1
     IF ( MOD(k,i) == 0 ) THEN
        is_prime = .FALSE.
        EXIT
     END IF
  END DO

END FUNCTION is_prime


PROGRAM askisi
  IMPLICIT NONE
  INTERFACE
     FUNCTION is_mersenne(k)
       IMPLICIT NONE
       INTEGER, INTENT (in) :: k
       LOGICAL :: is_mersenne
       INTEGER :: n
     END FUNCTION is_mersenne

     FUNCTION is_prime(k)
       IMPLICIT NONE
       INTEGER, INTENT (in) :: k
       LOGICAL :: is_prime
     END FUNCTION is_prime
  END INTERFACE

  INTEGER :: i
  
  OPEN(unit=45, file="mersenne_prime.txt", action="write",status="replace")

  DO i=1,1000000
     IF (is_mersenne(i) .AND. is_prime(i)) WRITE(45,*) i
  END DO

  CLOSE(45)
  
END PROGRAM askisi
