#include <stdio.h>
#include <math.h>

/* 関数のプロトタイプ宣言 */
long long int is_perfect(int);
int is_prime(long long int);
long long int triangle(long long int);
int is_triangle(long long int n);

int main(){

  int i,j;
  long long int n=0;
  for(i=1; i<32; i++){
    /* 2^(n-1)Mnが完全数かどうかを確認 */
    if( !(n = is_perfect(i)) ) continue;
    /* 完全数nが三角数かどうかを確認 */
    if(j=is_triangle(n)){
      printf("完全数%lld(=2^(%d-1)*(2^%d-1))は三角数 (%d*(%d+1)/2).\n", n, i,i,j, j);
    }else{
      printf("完全数%lld は三角数でない\n", n);
    }
  }

  return 0;
}

/* Mn = 2^n - 1 が素数かどうかを確認し，2^(n-1)Mnが完全数かどうかを調べる関数 */
/* Mnが素数のとき，2^(n-1)Mnは完全数となり，また偶数の完全数はその形に限られる */
/* 完全数ならその値を，そうでないなら0を返す */
long long int is_perfect(int n){
  /* 1<<n = 2^n を利用 */
  long long int Mn = (1<<n) - 1;
  if(is_prime(Mn)) return Mn << (n-1);
  else return 0;
}

/* nが素数かどうかを判定する関数 */
/* 素数なら1，そうでないなら0を返す */
int is_prime(long long int n){
  /* 1は素数ではない */
  if(n < 2) return 0;

  /* sqrt(n)までのすべてのiで割りきれなければ素数 */
  long long int i;
  for(i=2; i*i<=n; i++){
    if(n%i==0) return 0;
  }
  return 1;
}

/* n番目の三角数を返す関数 */
/* n番目の三角数は，n(n+1)/2 で表される */
long long int triangle(long long int n){
 return n*(n+1)/2;
}

/* nが三角数かどうかを返す関数 */
/* 三角数なら1，そうでないなら0を返す */
int is_triangle(long long int n){
  /* i(i+1)/2=n　を解くと，i=-1/2+sqrt(1/4+2n) */
  long long int i = sqrt(0.25+n*2)-0.5;
  if(triangle(i) == n) return i;
  return 0;
}
