import java.util.*;
import java.io.*;
import java.net.*;
import java.lang.*;

public class matrixwork 
{
   public static void main(String args[]) throws IOException
   {
      int job_id = 1;
      int task_id = Integer.parseInt(args[0]);

      String main_pt_name;
      int main_pt_no;
      String gp_name;
      int gp_no;
      String pt_name;
      int pt_no;

      int matA[][] = new int[10][10];
      int matB[][] = new int[10][10];
      int matC[][] = new int[10][10];

      int i, j, k, status;
      int rowA, colA;
      int rowB, colB;
      int no, val;
      i = 0;

      JMPF def_obj;
 
      gp_name = "gp1";
      pt_name = String.valueOf(task_id);
      main_pt_name = "main";
      def_obj = new JMPF(job_id, task_id);
      pt_no = def_obj.CreatePort(pt_name);
		while(true)
		{
      	status = def_obj.AddMember(gp_name, pt_no);
         System.out.println("The status is : " + status);
			if( status > 0 )
				break;
		}


      rowA = def_obj.BlockReceiveInt(pt_no);
      colA = def_obj.BlockReceiveInt(pt_no);
      rowB = def_obj.BlockReceiveInt(pt_no);
      colB = def_obj.BlockReceiveInt(pt_no); 

      for (i = 0; i < rowB; i++)
      {
         for (j = 0; j < colB; j++)
         {
            matB[i][j] = def_obj.BlockReceiveInt(pt_no);
//            System.out.println("The received data is : " + matB[i][j]);
         }
      }

      for (j = 0; j < colA; j++)
      {
         i = Integer.parseInt(pt_name);
         matA[i][j] = def_obj.ReceiveInt(pt_no);
//         System.out.println("The received data is : " + matA[i][j]);
      }

      status = def_obj.RemoveMember(gp_name, pt_no);

      System.out.println("The values of matrix A : " );
      for (i = 0; i < rowA; i++)
      {
         for (j = 0; j < colA; j++)
            System.out.print(matA[i][j] + "   ");
         System.out.println("\n");
      }

      System.out.println("The values of matrix B : " );
      for (i = 0; i < rowB; i++)
      {
         for (j = 0; j < colB; j++)
            System.out.print(matB[i][j] + "   ");
         System.out.println("\n");
      }

      no = Integer.parseInt(pt_name);
      for (k = 0; k < colB; k++)
      {
         val = 0;
         for (i = 0, j = 0; i < rowB || j < colA; i++, j++)
         {
            val = val + matA[no][j] * matB[i][k];
         }

         matC[no][k] = val;
      }

      System.out.println("The values of matrix C : " );
      for (i = 0; i < rowA; i++)
      {
         for (j = 0; j < colB; j++)
            System.out.print(matC[i][j] + "   ");
         System.out.println("\n");
      }

      main_pt_no = def_obj.LocatePort(main_pt_name);

      synchronized(def_obj)
      {
         for (j = 0; j < colB; j++)
         {
            String str = String.valueOf(no) + " " + String.valueOf(j) + " "
                                        + String.valueOf(matC[no][j]);
            status = def_obj.Send(main_pt_no, str);
//            System.out.println("The data send is : " + matC[no][j]);
//            System.out.println("The status of sending is ; " + status);
         }
      }
      def_obj.ClosePorts();
   }
}


