#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

#include "build_tree.h"
#include "tree.h"
#include "queue.h"
#include "pph.h"

int old[MAXSIZE];
int divide[MAXSIZE];
int divide1[MAXSIZE];
int ptr = 0;

struct NODE {
	struct NODE *next;
	struct NODE *next2;
	struct NODE *prev;
	int num;
};

NODE Ef[MAXSIZE];
NODE En[MAXSIZE];
SearchTree P,C,Et,Es;
int component[MAXSIZE];

void depth_first_search1(int v) {
	old[v] = 1;
	NODE *tt = Ef[v].next;
	divide1[ptr++] = v;
	
	while(tt!=NULL) {
		if(old[tt->num]==0)
			depth_first_search1(tt->num);
		tt = tt->next;
	}
	
	tt = En[v].next;
	while(tt!=NULL) {
		if(old[tt->num]==0)
			depth_first_search1(tt->num);
		tt = tt->next;
	}
}

void depth_first_search2(NODE *Ef,int v,int color) {
	old[v] = 1;
	NODE *tt = Ef[v].next;
	component[v] = color;
	divide[ptr++] = v;
	//printf("Enter %d\n",v+1);
	while(tt!=NULL) {
		if(old[tt->num]==0)
			depth_first_search2(Ef,tt->num,color);
		tt = tt->next;
	}
}

bool expand00(char a,char b) {
	if(a=='0' && b=='0')
		return true;
	else if(a=='2' && b=='0')
		return true;
	else if(a=='0' && b=='2')
		return true;
	else if(a=='2' && b=='1')
		return true;
	else if(a=='1' && b=='2')
		return true;
	else if(a=='0' && b=='1')
		return true;
	else
		return false;
}

bool expand01(char a,char b) {
	if(a=='0' && b=='1')
		return true;
	//else if(a=='2' && b=='1')
	//	return true;
	else if(a=='0' && b=='2')
		return true;
	else
		return false;
}

bool expand10(char a,char b) {
	if(a=='1' && b=='0')
		return true;
	else if(a=='2' && b=='0')
		return true;
	//else if(a=='1' && b=='2')
	//	return true;
	else
		return false;
}

bool expand11(char a,char b) {
	if(a=='1' && b=='1')
		return true;
	else if(a=='2' && b=='1')
		return true;
	else if(a=='1' && b=='2')
		return true;
	else
		return false;
}

void unionf(int u,int v) {
	NODE *newnode = new NODE;
	newnode->num = v;
	newnode->next = Ef[u].next;
	newnode->next2 = Ef[u].next;
	newnode->prev = NULL;
	
	if(Ef[u].next!=NULL)
		Ef[u].next->prev = newnode;
		
	Ef[u].next = newnode;
	Ef[u].next2 = newnode;
}

void unionn(int u,int v) {
	NODE *newnode = new NODE;
	newnode->num = v;
	newnode->next = En[u].next;
	newnode->prev = NULL;
	
	if(En[u].next!=NULL)
		En[u].next->prev = newnode;
		
	En[u].next = newnode;
}

bool removen(int v,int u) {
	NODE *neighbor;
	neighbor = En[v].next;
	int hit = 0;
	
	while(neighbor!=NULL) {
		if(neighbor->num == u) {
			hit = 1;
			break;
		}
		neighbor = neighbor->next;
	}
	
	if(hit==1) {
		if(neighbor->prev!=NULL) {
			if(neighbor->next == NULL)
				neighbor->prev->next = NULL;
			else {
				neighbor->prev->next = neighbor->next;
				neighbor->next->prev = neighbor->prev;
			}
		} else {
			if(neighbor->next == NULL)
				En[v].next = NULL;
			else {
				En[v].next = neighbor->next;	
				neighbor->next->prev = NULL;
			}
		}
		//printf("Delete %d %d DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD\n",v,u);
	} else {
		//printf("Can't find %d,%d to delete\n",v,u);
		return false;
	}
	return true;
}

void showEf() {
	int i=0;
	NODE *temp;
	
	for(i=0;i<1000;i++) {
		temp = Ef[i].next;
		
		if(temp!=NULL)
			printf("%d",i+1);
			
		while(temp!=NULL) {
			printf(" %d",temp->num+1);
			temp = temp->next;
		}
		if(Ef[i].next!=NULL)
			printf("\n");
	}
	printf("end showing ef\n");	
}

void showEn() {
	int i=0;
	NODE *temp;
	
	for(i=0;i<1000;i++) {
		temp = En[i].next;
		
		if(temp!=NULL)
			printf("%d",i+1);
			
		while(temp!=NULL) {
			printf(" %d",temp->num+1);
			temp = temp->next;
		}
		if(En[i].next!=NULL)
			printf("\n");
	}
	printf("end showing en\n");	
}

void ResetEf(int len) {
	int i;
	NODE *temp;
	
	for(i=0;i<len;i++) {
		temp = Ef[i].next;
		Ef[i].next2 = Ef[i].next;
		/*
		while(temp!=NULL) {
			temp->next2 = temp->next;
			temp = temp->next;
		}*/
	}
}

bool BuildGraph(char *M,int m,int n,int *ex)  {
	int i,j,jp;
	bool Is00,Is01,Is10,Is11,Is22;

	for(j=0;j<m;j++) {
		for(jp=0;jp<j;jp++) {
			Is00 = Is01 = Is10 = Is11 = Is22 = false;
			for(i=0;i<n;i++) {
				if(M[i*m+jp]=='2' && M[i*m+j]=='2') 
					Is22 = true;
				else {
					if(expand00(M[i*m+jp],M[i*m+j]))
						Is00 = true;
					if(expand01(M[i*m+jp],M[i*m+j]))
						Is01 = true;
					if(expand10(M[i*m+jp],M[i*m+j]))
						Is10 = true;
					if(expand11(M[i*m+jp],M[i*m+j]))
						Is11 = true;
				}
				if(Is01 && Is10 && Is11)
					return false;
				else if(Is00 && Is11 && Is22)
					break;
			}
			
			if(Is01 && Is10 && Is11)
				return false;
			else if(Is00 && Is11 && Is22) {
				unionf(jp,j);
				ex[jp*m+j] = 0;
				
				unionf(j,jp);
				ex[j*m+jp] = 0;
				//printf("inphase %d %d\n",jp+1,j+1);
				//numf++;
			} else if(Is01 && Is10 && Is22) {
				unionf(jp,j);
				ex[jp*m+j] = 1;
				
				unionf(j,jp);
				ex[j*m+jp] = 1;
				//printf("outphase %d %d\n",jp+1,j+1);
				//numf++;
			} else if(Is22) {
				unionn(jp,j);
				ex[jp*m+j] = -1;
				
				unionn(j,jp);
				ex[j*m+jp] = -1;
				//printf("other %d %d\n",jp+1,j+1);
				//numn++;
			}
		}
	}
	//printf("NUMBER: %d %d\n",numf,numn);
	return true;
}

void check_empty_Ef(Queue ET,int *ex,int column) {
	int i,j,v,u,hasEf = 0;
	for(i=0;i<column*column;i++) {
		if(ex[i]==1) {
			hasEf = 1;
			break;
		}
	}
	
	if(hasEf==0) {
		NODE *temp;
	
		for(j=0;j<1000;j++) {
			temp = En[j].next;
		
			if(temp!=NULL) {
				v = j;
				u = temp->num;
				break;
			}
		}
	
		ElementTypeS *element = new ElementTypeS;
            	element->v = v;
            	element->u = u;
		Enqueue( *element, ET );
		Et = Insert2(v,u,Et);
	}
}

bool isEfEn(int v,int u) {
	NODE *neighbor;
	
	neighbor = Ef[v].next;
	while(neighbor!=NULL) {
		if(neighbor->num == u)
			return true;
		neighbor = neighbor->next;
	}
	
	neighbor = En[v].next;
	while(neighbor!=NULL) {
		if(neighbor->num == u)
			return true;
		neighbor = neighbor->next;
	}
	return false;
}

int xxor(int x,int y) {
	if(x!=y)
		return 1;
	else
		return 0;
}

int *search,*ex,*next,*prev;

void process(int v,int m) {
	NODE *neighbor;
	int u;
	Position pos;

	neighbor = En[v].next;
	while(neighbor!=NULL) {
		u = neighbor->num;
		//printf("neighbor is %d\n",u+1);
		if(ex[v*m+u]==-1) {
			if((pos = Find(u,P)) != NULL) {
				//printf("do step 1\n");
				Stack S = CreateStack(MAXSIZE);
				while(prev[v]!=-1 && next[u]!=-1 && ex[v*m+u]==-1 && !isEfEn(prev[v],u)) {
					ElementTypeS *element = new ElementTypeS;
            				element->u = u;
            				Push( *element, S );
            				u = next[u];
				}
				
				//if(prev[v]!=-1 && isEfEn(prev[v],u) && ex[v*m+u] == -1) {
				if(prev[v]!=-1 && ex[v*m+u] == -1) {
					if(ex[prev[v]*m+u]!=-1) {
						//printf("%d %d %d\n",ex[prev[v]*m+u],ex[v*m+prev[v]],ex[prev[v]*m+v]);
						if(ex[v*m+prev[v]]!=-2 && ex[v*m+prev[v]]!=-1) {
							ex[v*m+u] = xxor(ex[prev[v]*m+u],ex[v*m+prev[v]]);
							ex[u*m+v] = ex[v*m+u];
						} else {
							ex[v*m+u] = xxor(ex[prev[v]*m+u],ex[prev[v]*m+v]);
							ex[u*m+v] = ex[v*m+u];
						}
					
						//Remove(ET, u, v);
						Et = Delete2(u,v,Et);
						//Remove(ET, v, u);
						Et = Delete2(v,u,Et);
						//Remove(ES, u, v);
						Es = Delete2(u,v,Es);
						//Remove(ES, v, u);
						Es = Delete2(v,u,Es);											
						//printf("SET %d %d %d\n",v+1,u+1,ex[v*m+u]);
					}
				}
				
				while( !IsEmpty( S ) ) {
					ElementTypeS e = Top( S );
					u = e.u;
					
					if(ex[u*m+next[u]]!=-2 && ex[u*m+next[u]]!=-1) {
						ex[v*m+u] = xxor(ex[v*m+next[u]],ex[u*m+next[u]]);
						ex[u*m+v] = ex[v*m+u];
					} else {
						ex[v*m+u] = xxor(ex[v*m+next[u]],ex[next[u]*m+u]);
						ex[u*m+v] = ex[v*m+u];
					}
						
					//printf("SET %d %d %d\n",v+1,u+1,ex[v*m+u]);
					
					//Remove(ET, v, u);
					Et = Delete2(v,u,Et);
					//Remove(ET, u, v);
					Et = Delete2(u,v,Et);
					//Remove(ES, v, u);
					Es = Delete2(v,u,Es);
					//Remove(ES, u, v);
					Es = Delete2(u,v,Es);
					Pop( S );
				}
				DisposeStack( S );
			} else if((pos = Find(u,C)) != NULL) {
				//printf("do step 2\n");
				Stack S = CreateStack(MAXSIZE);
				
				while(prev[v]!=-1 && prev[u]!=-1 && ex[v*m+u]==-1 && !isEfEn(prev[v],u)) {
					ElementTypeS *element = new ElementTypeS;
			
            				element->u = u;
            				Push( *element, S );
            				u = prev[u];
				}
				
				//if(prev[v]!=-1 && isEfEn(prev[v],u) && ex[v*m+u] == -1) {
				if(prev[v]!=-1 && ex[v*m+u] == -1) {
					//printf("ex: %d %d\n",ex[prev[v]*m+u],ex[v*m+prev[v]]);
					if(ex[prev[v]*m+u]!=-1) {
						if(ex[v*m+prev[v]]!=-2 && ex[v*m+prev[v]]!=-1) {
							ex[v*m+u] = xxor(ex[prev[v]*m+u],ex[v*m+prev[v]]);
							ex[u*m+v] = ex[v*m+u];
						} else {
							ex[v*m+u] = xxor(ex[prev[v]*m+u],ex[prev[v]*m+v]);
							ex[u*m+v] = ex[v*m+u];
						}
					
						//Remove(ET, u, v);
						Et = Delete2(u,v,Et);
						//Remove(ET, v, u);
						Et = Delete2(v,u,Et);
						//Remove(ES, u, v);
						Es = Delete2(u,v,Es);
						//Remove(ES, v, u);
						Es = Delete2(v,u,Es);
						//printf("SET %d %d %d\n",v+1,u+1,ex[v*m+u]);
					}
				}
				
				while( !IsEmpty( S ) ) {
					ElementTypeS e = Top( S );
					u = e.u;
					//printf("next: %d %d %d\n",u,prev[u],prev[u]*m+u);
					//printf("ex: %d %d\n",ex[v*m+prev[u]],ex[u*m+prev[u]]);
					//printf("ex2: %d %d\n",ex[v*m+prev[u]],ex[prev[u]*m+u]);
					
					if(ex[u*m+prev[u]]!=-2 && ex[u*m+prev[u]]!=-1) {
						ex[v*m+u] = xxor(ex[v*m+prev[u]],ex[u*m+prev[u]]); // not sure
						ex[u*m+v] = ex[v*m+u];
					} else {
						ex[v*m+u] = xxor(ex[v*m+prev[u]],ex[prev[u]*m+u]);
						ex[u*m+v] = ex[v*m+u];
					}
						
					//printf("SET %d %d %d\n",v+1,u+1,ex[v*m+u]);
					
					//showQueue(ET);
					//Remove(ET, v, u);
					Et = Delete2(v,u,Et);
					//Remove(ET, u, v);
					Et = Delete2(u,v,Et);
					//Remove(ES, v, u);
					Es = Delete2(v,u,Es);
					//Remove(ES, u, v);
					Es = Delete2(u,v,Es);
					//showQueue(ET);
					Pop( S );
				}
				DisposeStack( S );
			} else {
				//printf("do step 3\n");
				ElementTypeS *element = new ElementTypeS;
            			element->v = v;
            			element->u = u;
            			//showStack(ET);
            			
            			//printf("%d %d\n",component[v],component[u]);
            			if(component[v] != component[u]) {
            				//printf("push %d %d to ET\n",v+1,u+1);
            				//Enqueue( *element, ET );
							Et = Insert2(v,u,Et);
            			} else {
            				//printf("push %d %d to ES\n",v+1,u+1);
            				//Enqueue( *element, ES );
							Es = Insert2(v,u,Es);
            			}
			}
		}
		neighbor = neighbor->next;
	}
}

Stack Set;

void SetEdges(int v,int m) {
	//printf("enter %d\n",v+1);
	NODE *neighbor;
	int u;
	//Position pos;
	P = Insert( v, P );
	C = Insert( v, C );
	search[v] = 1;
	
	process(v,m);


	ElementTypeS *element = new ElementTypeS;
    element->u = v;
    Push( *element, Set );

	while( !IsEmpty( Set ) ) {
		//while(neighbor!=NULL) {
		while(1) {
			ElementTypeS e = Top( Set );
			v = e.u;
			neighbor = Ef[v].next2;

			if(neighbor!=NULL) {
				Ef[v].next2 = neighbor->next;
				u = neighbor->num;
			} 
			else
				break;
		/*	
			else
				Ef[v].next2 = NULL;
*/
			//if(neighbor==NULL)
			//	break;
		
			if(search[u] == -1) {
				search[u] = 1;
				next[v] = u;
				prev[u] = v;
				P = Insert( u, P );
				C = Insert( u, C );
				process(u,m);
				element = new ElementTypeS;
				element->u = u;
				Push( *element, Set );
				P = Delete(u,P);
				//SetEdges(u,m);		
			}
			//neighbor = neighbor->next;
		}

		Pop( Set );
	}

	P = Delete( v, P );
		
	//printf("leave %d\n",v+1);
}


char *E2M(char *M,int row,int column,int *ex) {
	char *Mp = new char[2*row*column+1];
	
	int i,j,k;
	int temp;
	
	for(i=0;i<2*row*column;i++) 
		Mp[i] = '2';
		
	for(i=0;i<row;i++) {
		k = 10000;
		for(j=0;j<column;j++) {
			if(M[i*column+j] == '0') {
				Mp[2*i*column+j] = '0';
				Mp[(2*i+1)*column+j] = '0';
			} else if(M[i*column+j] == '1') {
				Mp[2*i*column+j] = '1';
				Mp[(2*i+1)*column+j] = '1';
			} else {
				if(k<j) {
					if(ex[k*column+j]==-1)
						ex[k*column+j] = 0;
						
					temp = xxor((int)Mp[2*i*column+k]-48,ex[k*column+j]);
						
					Mp[2*i*column+j] = (char)(temp+48);
					Mp[(2*i+1)*column+j] = 	(char)(1-temp+48);
				} else {
					Mp[2*i*column+j] = '1';
					Mp[(2*i+1)*column+j] = '0';
				}
			}
			
			if(M[i*column+j] == '2') 
				k = j;
		}
	}
	
	return Mp;
}

void delete_link(NODE *E) {
	int i=0;
	NODE *temp,*temp1;
	
	for(i=0;i<1000;i++) {
		temp = E[i].next;
			
		while(temp!=NULL) {
			temp1 = temp->next;
			delete temp;
			temp = temp1;
		}
	}
}

char *generate_default(char *cvector, char *M,int row,int column) {
	int i,j;
	int one,zero;
	
	for(i=0;i<column;i++) {
		one = 0;
		zero = 0;
		for(j=0;j<row;j++) {
			if(M[j*column+i]=='1')
				one++;
			else if(M[j*column+i]=='0')
				zero++;
		}
		if(zero >= one)
			cvector[i] = '0';
		else
			cvector[i] = '1';
	}
	cvector[i] = '\0';
	return cvector;
}

char *read_vector(char *cvector,char *filename,int row, int num,char *M) {
	cvector = new char[num+1];
	FILE *fp;
	int i = 0;
	int tt;
	
	if(strcmp(filename,"d")!=0 && strcmp(filename,"m")!=0) {
		fp = fopen(filename,"r");
		
		for(i=0;i<num;i++) {	
			if(fscanf(fp,"%d",&tt)==EOF) {
				printf("vector information error!\n");
				exit(0);
			}
			cvector[i] = (char)tt+48;
		}
		cvector[i] = '\0';
		fclose(fp);
	} else if(strcmp(filename,"m")==0) {
		cvector = generate_default(cvector,M,row,num);
	} else if(strcmp(filename,"d")==0) {
		for(i=0;i<num;i++) 
			cvector[i] = '0';
		cvector[i] = '\0';
	}
	return cvector;
}

char *convert_data(char *M, char *vector, int row, int column) {
	int i,j;
	
	for(i=0;i<column;i++) {
		if(vector[i] == '1') {
			for(j=0;j<row;j++) {
				if(M[j*column+i]=='1')
					M[j*column+i] = '0';
				else if(M[j*column+i]=='0')
					M[j*column+i] = '1';
			}
		}
	}
	
	return M;
}

char *convert_back(char *output,int row,int column,char *cvector) {
	int i,j;
	row = row*2;
	for(i=0;i<column;i++) {
		if(cvector[i]=='1') {
			for(j=0;j<row;j++) {
				if(output[j*column+i]=='0')
					output[j*column+i] = '1';
				else if(output[j*column+i]=='1')
					output[j*column+i] = '0';
			}
		}
	}
	return output;
}

int main(void) {
	FILE *fp,*fp1;
	int column,row,digit,u,v,color=1;
	int i = 0;
	char *M,*Mp;
	
	fp = fopen("rr","r");
	fscanf(fp,"%d%d",&row,&column);
	
	M = new char[row*column+1];
	ex = new int[column*column+1];
	search = new int[column+1];
	next = new int[column+1];
	prev = new int[column+1];
		
	while(fscanf(fp,"%d",&digit)!=EOF) {
		M[i] = (char)digit+48;
		i++;
	}
	
	fclose(fp);
	
	for(i=0;i<MAXSIZE;i++) {
		Ef[i].next = NULL;
		En[i].next = NULL;
	}
	
	for(i=0;i<column*column+1;i++)
		ex[i] = -2;
	
	for(i=0;i<column;i++) {
		prev[i] = -1;
		next[i] = -1;
	}
			
	bool issolution = BuildGraph(M,column,row,ex);
	
	int l = 0;
	
	for(i=0;i<MAXSIZE;i++) {
		old[i]=0;
		divide1[i] = -2;
	}
	
	ptr = 0;
	
	for(i=0;i<column;i++) {
		if(old[i]==0) {
			l++;
			depth_first_search1(i);	
			divide1[ptr++] = -1;
		}
	}

	int k = 0;
	for(i=0;i<MAXSIZE;i++) {
		old[i]=0;
		component[i] = -1;
		divide[i] = -2;
	}
	
	ptr = i = 0;
	divide[0] = divide[1] = -1;
	ptr = 2;
	
	while(divide1[i]!=-2) {
		if(old[divide1[i]]==0 && divide1[i]!=-1) {
			k++;
			depth_first_search2(Ef,divide1[i],color);
			color++;	
			divide[ptr++] = -1;
		} else if(divide1[i]==-1) {
			divide[ptr++] = -1;
		}
		i++;
	}
	
	//printf("finish13\n");
	//for(i=0;i<column*column;i++)
	//	printf("%d ",ex[i]);
			
	if(!issolution) {
		//printf("No Tree!\n");
		fp1 = fopen("cc","w");
		fprintf(fp1,"0");
		fclose(fp1);
		exit(0);
	}
	
	C = MakeEmpty( NULL );
	P = MakeEmpty( NULL );
	Et = MakeEmpty2( NULL );
	Es = MakeEmpty2( NULL );

	Queue ET;
	Queue ES;
	
	ET = CreateQueue(column*column/2);
	ES = CreateQueue(column*column/2);
	Set = CreateStack(MAXSIZE);
	
	//printf("finish14\n");

	for(i=0;i<column+1;i++)
		search[i] = -1;
	
	check_empty_Ef(ET,ex,column);
	
	//printf("finish15\n");
	//ResetEf(row);

	for(i=0;i<column;i++) {
		//printf("%dth RUN\n",i);
		if(Ef[i].next!=NULL && search[i]==-1) {	
			SetEdges(i,column);
		}	
		
		//C = MakeEmpty( NULL );
		//P = MakeEmpty( NULL );
	}

	//printf("finish16\n");

	//while( !IsEmpty( ES ) ) {
	while(Es!=NULL) {
				v = Es->Element;
				SearchTree sub = Es->Child;
				u = sub->Element;
				Es = Delete2(v,u,Es);
				//printf("EEEEEEEEE %d %d\n",v,u);
				//getchar();
				//ElementTypeS e = Front( ES );
				//Dequeue(ES);
				//v = e.v;
				//u = e.u;
				//printf("ES: v and u are %d %d %d\n",i,v+1,u+1);
				//ResetEf(row);
				SetEdges(v,column);
	}
	
	//printf("finish2\n");

	//while( !IsEmpty( ET ) ) {
	while(Et!=NULL) {
				v = Et->Element;
				SearchTree sub = Et->Child;
				
				u = sub->Element;
				Et = Delete2(v,u,Et);
				//printf("TTTTTTTTT %d %d\n",v,u);
				//getchar();
				//getchar();
				//ElementTypeS e = Front( ET );
				//Dequeue(ET);
				//v = e.v;
				//u = e.u;
				
				//printf("ET: v and u are %d %d %d\n",i,v+1,u+1);
				
				ex[v*column+u] = 0;
				ex[u*column+v] = 0;
				//printf("SET %d %d %d\n",v+1,u+1,ex[v*column+u]);
					
				unionf(v,u);
				unionf(u,v);
				
				removen(v,u);
				removen(u,v);
				
				//if((pos = Find(v,C)) != NULL) {
				//	prev[u] = v;
				//	next[v] = u;
				//	SetEdges(u,search,column,ET,ES,ex,next,prev);
				//} else {
				//if(search[v]==-1)
				//ResetEf(row);
				SetEdges(v,column);
				//}
	}

	delete search;
	delete prev;
	delete next;
	DisposeQueue( ET );
	DisposeQueue( ES );
	MakeEmpty(C);
	MakeEmpty(P);
	delete_link(Ef);
	delete_link(En);
	
	Mp = E2M(M,row,column,ex);
	
	delete M;
	delete ex;
	
	char tt;
	fp = fopen("temp.1co","w");
	fprintf(fp,"%d %d\n",2*row,column);
	for(i=0;i<2*row;i++) {
		for(int j=0;j<column;j++) {
			tt = Mp[i*column+j];
			fprintf(fp,"%c ",tt);
		}
		fprintf(fp,"\n");
	}
	fclose(fp);
	
	//printf("finish4\n");

	int pass = build_tree();
	
	if(pass==0) {
		//printf("No tree!\n");
		fp1 = fopen("cc","w");
		fprintf(fp1,"0");
		fclose(fp1);
		exit(0);
	}
	
	fp = fopen("rrco","w");
	fprintf(fp,"%d %d\n",2*row,column);
	for(i=0;i<2*row;i++) {
		for(int j=0;j<column;j++) {
			tt = Mp[i*column+j];
			fprintf(fp,"%c ",tt);
		}
		fprintf(fp,"\n");
	}
	fclose(fp);
	
	delete Mp;	
	
	fp1 = fopen("cc","w");
	fprintf(fp1,"1");
	fclose(fp1);
	
	fp1 = fopen("dd","w");
	
	if(k==l)
		fprintf(fp1,"1");
	else
		fprintf(fp1,"0");
	fclose(fp1);
		
	return 1;
} 
