import java.io.File;
import java.io.FileNotFoundException;
import java.util.NoSuchElementException;
import java.util.Formatter;
import java.util.FormatterClosedException;
import java.util.Scanner;

class snake
{
	static Scanner input1;
	static Scanner input2;
	static Scanner input3;
	static Scanner input4;
	static Scanner input5;
	static Scanner input6;
	static Scanner input7;
	static Scanner input8;
	static Scanner input9;
	static Scanner input10;
		
	static Formatter output1;//for writing vertical frame tiles without any manipulation to the original .tile structure
	static Formatter output2;//for writing horizontal frame tiles without any manipulation to the original .tile structure
	static Formatter output3;//for writing seed tiles without any manipulation to the original .tile structure
	static Formatter output4;//for writing all broken frame tiles into snake_frame.txt file
	static Formatter output5;
	
	public static void main(String args[])
	{
		int strength[] = new int[4000];
		int glue[][][] = new int[1000][1000][4];
		int n , s, e, w;//they are the four glues for four different sides of a computational tile
		int a, b, c, d;//
		int x;//would help to find the biggest glue no. before any manipulation
		int i,j;//would work as indexes for the tile nos. inside a broken computational tile
		int big=0;//highest number of thew glue upto that point
		int big1=0 , big2 = 0;
		int k;//k = m /2 which would be used for utilizing for the Ashish Goel's Snake condition
		int m;
		int temp = 0; //a temperory variable which would be used for giving strength value to the glue numbers
		int num_tile_types = 0;
		int num_binding_types = 0;
		int big3 = 0;//for finding the biggest glue number in the computational tiles 
		try{
		
			
			output1 = new Formatter("snake_vertical_frame.txt");
			output2 = new Formatter("snake_horizontal_frame.txt");
			output3 = new Formatter("snake_seed.txt");
			output4 = new Formatter("snake_frame_broken.txt");
			output5 = new Formatter("snake.tiles");
			
			input1 = new Scanner(new File("glues2.txt"));
			input2 = new Scanner(new File("glues2.txt"));
			input3 = new Scanner(new File("snake_vertical_frame.txt"));
			input4 = new Scanner(new File("snake_horizontal_frame.txt"));
			input5 = new Scanner(new File("snake_seed.txt"));
			input6 = new Scanner(new File("glues.txt"));
			input7 = new Scanner(new File("snake_frame_broken.txt"));
			input8 = new Scanner(new File("snake_frame_broken.txt"));
			input9 = new Scanner(new File("snake_frame_broken.txt"));
			input10 = new Scanner(new File("glues.txt"));
			
			System.out.println("We can give you the tileset for snake of m*m give us the value of m \n allowable values of n are 2,4,6 and so on ");
			Scanner input = new Scanner(System.in);
			
			m = input.nextInt();
			k = m/2;
			//System.out.printf("%d\n",k);
			
			while(input1.hasNext())//finding the biggest no. glue out of all the glues present
			{
				x = input1.nextInt();
				if(big<x)
					big=x;
			}	
			//System.out.printf("%d\n",big);
				
			while(input2.hasNext())//seperating the frames into vertical,horizontal and seed files
				{
					n=input2.nextInt();
					e=input2.nextInt();
					s=input2.nextInt();
					w=input2.nextInt();
					
					if(e==0 && s!=0)
						output1.format("%d\t%d\t%d\t%d\n",n,e,s,w);
					if(e!=0 && s==0)
						output2.format("%d\t%d\t%d\t%d\n",n,e,s,w);
					if(e==0 && s==0)
						output3.format("%d\t%d\t%d\t%d\n",n,e,s,w);
					
				
				}	
				output1.close();
				output2.close();
				output3.close();
			//seed is being written onto the snake_broken_frame.txt file	
				
			output4.format("%d\t%d\t%d\t%d\n",input5.nextInt(),input5.nextInt(),input5.nextInt(),input5.nextInt());	
			
				
			//vertical frame tiles being broken for snake
			
			
			a= b= c= d= 0;
			int hr[] = new int[m+1];//m+1
			int vr[] = new int[2*m]; //2*m		
			while(input3.hasNext())
			{
				a = input3.nextInt();
				b = input3.nextInt();
				c = input3.nextInt();
				d = input3.nextInt();
				
				for(i = 0; i<= m-1; i++) //i <= m-1
					vr[i] = b;
				
				for(i = m; i<= 2*m - 1; i++) //i = n; i <= 2*n - 1
					vr[i] = d;
				
					hr[0] = c;
				
					hr[m] = a; //hr[n]
				
				for(i = 1; i <= m-1; i++ ) //	i <=n-1		
					hr[i] = ++big;
				
				for(i = 0;i < m; i++ ) //i<n
				{	
					output4.format("%d\t%d\t%d\t%d\n",hr[i+1], vr[i], hr[i], vr[i+m]);
				}
			}
				
				//horizontal frame tiles being broken for snake
			
			
			a= b= c= d= 0;
			int vr1[] = new int[m+1];//n+1
			int hr1[] = new int[2*m]; //2*n		
			while(input4.hasNext())
			{
				a = input4.nextInt();
				b = input4.nextInt();
				c = input4.nextInt();
				d = input4.nextInt();
				
				for(i = 0; i<= m-1; i++) //i <= n-1
					hr1[i] = c;
				
				for(i = m; i<= 2*m - 1; i++) //i = n; i <= 2*n - 1
					hr1[i] = a;
				
					vr1[0] = b;
				
					vr1[m] = d; //vr1[n]
				
				for(i = 1; i <= m-1; i++ ) //	i <=n-1		
					vr1[i] = ++big;
				
				for(i = 0;i < m; i++ ) //i<n
				{
					output4.format("%d\t%d\t%d\t%d\n",hr1[i+m], vr1[i], hr1[i], vr1[i+1]); //hr1[i+n]
				}
			}
			
			while(input10.hasNext())
			{	temp = input10.nextInt();
				if(temp > big3)
					big3 = temp;	
			}
			for(i = big3 +1;i <= big; i++)
				strength[i] = 2;
			
			
			
			//for spliting the computational tiles
			i=1;
			j=1;
			big1 = big;
			System.out.printf("big befor while %d",big);
			while(input6.hasNext())
			{
				System.out.printf("\n value of big in beginning %d\n",big);						
				
				big1 = big;
				
				n=input6.nextInt();
				e=input6.nextInt();
				s=input6.nextInt();
				
				w=input6.nextInt();
				
				for(j=1;j<=2*k;j++)// filling in the north side
				{
					for(i=1;i<=2*k;i++)
					{
						if(j==i+1 && i%2==0 && k!=1)//for T(2i,2i+1) North condition
						{
							glue[i][j][0] = ++big;
							temp = glue[i][j][0];
							strength[temp] = 2;
						}
						else
						if(i%2==0 && j==1 && k!=1 && i != 2*k)//for T(2i,1) North condition
						{
							glue[i][j][0] = 0;
							//temp = glue[i][j][0];
							//strength[temp] = 0;
						}
						else
						if(i==2*k-2 && j==2*k && k!=1)//for T(2k-2,2k) North condition
						{
							glue[i][j][0] = ++big;
							temp = glue[i][j][0];
							strength[temp] = 2;
						}
						else
						if(i==2*k)//for T(2k,j) North condition
						{
							glue[i][j][0] = n;
							temp = glue[i][j][0];
							strength[temp] = 1;
						}
						else//for a normal case
						{
							glue[i][j][0] = ++big;
							temp = glue[i][j][0];
							strength[temp] = 1;
						}
					}
				}//end of for
				
				//filling in the south side
				big = big1;
				System.out.printf("\n%d\n",big);
				for(j=1;j<=2*k;j++)// filling in the south side
				{
					for(i=1;i<=2*k;i++)
					{
						if(j==i && i%2==1 && i!=1 && k!=1)//for T(2i+1,2i+1) South condition
						{
							glue[i][j][2] = ++big;
							temp = glue[i][j][2];
							strength[temp] = 2;
						}
						else
						if(i%2==1 && i!=1 && j==1 && k!=1)
						{
							glue[i][j][2] = 0;
							//temp = glue[i][j][2];
							//strength[temp] = 0;
						}
						else
						if(i==2*k-1 && j==2*k && k!=1)
						{
							glue[i][j][2] = ++big;
							temp = glue[i][j][2];
							strength[temp] = 2;
						}
						else
						if(i==1)
						{
							glue[i][j][2] = s;
							temp = glue[i][j][2];
							strength[temp] = 1;
						}
						else
						{
							glue[i][j][2] = ++big;
							temp = glue[i][j][2];
							strength[temp] = 1;
						}
					}
				}//end of for
				
				//for filling the east side
				big2 = big;
				
				for(j=1;j<=2*k;j++)// filling in the east side
				{
					for(i=1;i<=2*k;i++)
					{
						if(i==1 && j%2==0 )//for T(1,2i) east condition
						{
							glue[i][j][1] = 0;
							//temp = glue[i][j][1];
							//strength[temp] = 0;
						}
						else
						if(i==j && i%2==0)
						{
							glue[i][j][1] = ++big;
							temp = glue[i][j][1];
							strength[temp] = 2;
						}
						else
						if(i==(2*k)-2 && j==2*k)
						{
							glue[i][j][1] = 0;
							//temp = glue[i][j][1];
							//strength[temp] = 0;
						}
						else
						if(j==1)
						{
							glue[i][j][1] = e;
							temp = glue[i][j][1];
							strength[temp] = 1;
						}
						else
						{
							glue[i][j][1] = ++big;
							temp = glue[i][j][1];
							strength[temp] = 1;
						}
					}
				}//end of for
				
				big = big2;
				
				for(j=1;j<=2*k;j++)// filling in the west side
				{
					for(i=1;i<=2*k;i++)
					{
						if(i==1 && j%2==1)//for T(1,2i-1) west condition
						{
							glue[i][j][3] = 0;
							//temp = glue[i][j][3];
							//strength[temp] = 0;
						}
						else
						if(i%2==0 && j==i-1 )
						{
							glue[i][j][3] = ++big;
							temp = glue[i][j][3];
							strength[temp] = 2;
						}
						else
						if(i==2*k-2 && j==2*k-1)
						{
							glue[i][j][3] = 0;
							//temp = glue[i][j][3];
							//strength[temp] = 0;
						}
						else
						if(j==2*k)
						{
							glue[i][j][3] = w;
							temp = glue[i][j][3];
							strength[temp] = 1;
						}
						else
						{
							glue[i][j][3] = ++big;
							temp = glue[i][j][3];
							strength[temp] = 1;
						}
					}
				}//end of for
				//for writting all the glues after breaking in snake_frame.txt
				for(i=1;i<= 2 * k; i++)
					for(j=1; j <= 2 * k; j++)
						output4.format("%d\t%d\t%d\t%d\n",glue[i][j][0],glue[i][j][1],glue[i][j][2],glue[i][j][3]);
									
			System.out.printf("\n value of big %d\n",big);						
			}
			output4.close();
			System.out.printf("\n value of big %d\n",big);						
			
			while(input7.hasNext())
			{	
				temp = input7.nextInt();
				if(temp > num_binding_types)
					num_binding_types = temp;
			}
			while(input8.hasNext())
			{	
				temp = input8.nextInt();
				temp = input8.nextInt();
				temp = input8.nextInt();
				temp = input8.nextInt();
				num_tile_types = num_tile_types + 1;
			}
			
			
			//now starting to make .tiles file
			
			
		 output5.format("tile edges matches {{N E S W}*}\n");
		 output5.format("num tile types=%d\n",num_tile_types);
		 output5.format("num binding types=%d\ntile edges={\n",num_binding_types);
		 //int p,q,r,s;
		 while(input9.hasNext())
		 {
		 	n=input9.nextInt();
		 	e=input9.nextInt();
		 	s=input9.nextInt();
		 	w=input9.nextInt();
		 	output5.format("{%d\t%d\t%d\t%d}\n",n,e,s,w);
		 }
		 output5.format("}\n");
		 output5.format("binding strengths=\n{");
			
			for(i = 1; i <= num_binding_types; i++)
			{
				output5.format("%d\t",strength[i]);
			}
			
			/*for(int d1=0; d1< glue_strength_2; d1++)
			{
				output1.format("2\t");
			}*/	 
			output5.format("}");
		 output5.close();
			
			
		}
		
	  catch ( SecurityException securityException )
      {
         System.err.println(
            "You do not have write access to this file." );
         System.exit( 1 );
      } // end catch
      catch ( FileNotFoundException filesNotFoundException )
      {
         System.err.println( "Error creating file." );
         System.exit( 1 );
      } // end catch
      catch ( FormatterClosedException formatterClosedException )
      {
            System.err.println( "Error writing to file." );
            return;
      } // end catch
      catch ( NoSuchElementException elementException )
      {
            System.err.println( "Invalid input. Please try again." );
            input6.nextLine(); // discard input so user can try again
      } // end catch
					
		
	}
}


