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

const long long int N=100000000;

int brojCifara(int n)
{
    int br=0;
    while(n>0)
    {
        br++;
        n=n/10;
    }
    return br;
}



int main(int argc, char **argv)
{
    int id,np;

    MPI_Init(&argc,&argv);

    MPI_Comm_rank(MPI_COMM_WORLD,&id);
    MPI_Comm_size(MPI_COMM_WORLD,&np);


    int *localniz;
    int localBrBrojeva=0;

    localniz=(int*)malloc(N*sizeof(int));


    for(int i=1+id;i<N;i+=np)
    {

        int d=brojCifara(i);

        int kvadrat=pow(i,2);

        for(int k=1;k<=d;k++)
        {
            int pom1=kvadrat%((int)(pow(10,k)));
            int pom2=kvadrat/((int)(pow(10,k)));

            if((pom1+pom2)==i)
            {
                localniz[localBrBrojeva++]=i;
                break;
            }
        }
    }

    if(id!=0)
    {
        MPI_Send(&localBrBrojeva,1,MPI_INT,0,20,MPI_COMM_WORLD);
        if(localBrBrojeva>0)
        {
            MPI_Send(localniz,localBrBrojeva,MPI_INT,0,21,MPI_COMM_WORLD);
        }
    }
    else
    {
        int *globalNiz=(int*)malloc(N*sizeof(int));
        int globalBrBrojeva=0;

        for(int i=1;i<np;i++)
        {
            int pomBr;
            MPI_Recv(&pomBr,1,MPI_INT,i,20,MPI_COMM_WORLD,NULL);
            if(pomBr>0)
            {
                int *bufer=(int*)malloc(pomBr*sizeof(int));
                MPI_Recv(bufer,pomBr,MPI_INT,i,21,MPI_COMM_WORLD,NULL);

                for(int j=0;j<pomBr;j++)
                {
                    globalNiz[globalBrBrojeva++]=bufer[j];
                }
            }

            
        }

        for(int k=0;k<localBrBrojeva;k++)//da uzme i svoje posto id=0 ne radi send
        {
            globalNiz[globalBrBrojeva++]=localniz[k];
        }


        for(int i=0;i<globalBrBrojeva;i++)
        {
            printf("%d\n",globalNiz[i]);
        }
    }

    MPI_Finalize();
    return 0;
}