import java.awt.*;

public class VertexStack
{
// here I fake enumeration
public static boolean NONFILLED = false;
public static boolean FILLED = true;

public VertexStack prev;   // pointer to previous link
public VertexStack next;  // pointer to next link
public VertexLink top;   // top of the stack pointer
public Color field[][]; // an array to which I am drawing
public boolean filled; // is the polygon to be filled or not ?
public VertexLink bot;// bottom of the stack pointer
public boolean loop; // a flag saying if this polygon is complete
public Color color; // the color of the polygon
public int height; // the height of the canvas
public int width; // the width of the canvas
public int count;// counter of the vertices
    
public VertexStack(int width_, int height_)
    {
	width = width_;
	height = height_;
	filled = NONFILLED;
	
	field = new Color[width][height];
	for(int i = 0; i<width; i++)
	    for(int j=0; j<height; j++)
		field[i][j] = Color.black;
	color = Color.white;
	
	top = null;
	bot = null;
	loop = false;
	count = 0;
    }

public boolean add(int x, int y)
    {
	if(loop)
	    return false;
	
	if(top==null)
	    {
		top = new VertexLink(x, y);
		bot = top;
		count++;
		return true;
	    }
	else if(top.x == x && top.y == y) // i do not allow dots or useless selfloops
	    {
		return false;
	    }
	else if(bot.x == x && bot.y == y) // here I created a loop
	    {
		top.next = bot;
		bot.prev = top;
		loop = true;
		count++;
		return true;
	    }
	else
	    {
		VertexLink temp = new VertexLink(x, y); // raised the top
		temp.prev = top;
		top.next = temp;
		top = temp;
		count++;
		return true;
	    }
    }

public boolean undo()
    {
	if(top==null)
	    return false;
	if(!loop)
	    {
		top = top.prev;
		if(top != null)
		    top.next = null;
		else
		    bot = null;
	    }
	else
	    {
		bot.prev = null;
		top.next = null;
		loop = false;
	    }
	count--;
	return true;
    }

public boolean cut(int x, int y)
    {
	boolean flag = false;
	VertexLink index = bot;
	for(int i=0; i<count; i++)
	    {
		if(index.x == x && index.y == y)
		    {
			flag = true;
			break;
		    }
		index = index.next;
	    }
	if(!flag)
	    return false;
	if(!loop)
	    {
		if(index == top)
		    {
			top = top.prev;
			if(top != null)
			    {
				top.next.prev = null;
				top.next = null;
			    }
			else
			    bot = null;
		    }
		else if(index == bot)
		    {
			bot = bot.next;
			if(bot != null)
			    {
				bot.prev.next = null;
				bot.prev = null;
			    }
			else
			    top = null;
		    }
		else
		    {
			index.next.prev = index.prev;
			index.prev.next = index.next;
			index.next = null;
			index.prev = null;
		    }
		count--;
		return true;
	    }
	else
	    {
		if(count == 2)
		    return false;
		else
		    {
			if(index == top)
			    {
				top = top.prev;
				top.next.prev = null;
				top.next.next = null;
				top.next = bot;
				bot.prev = top;
			    }
			else if(index == bot)
			    {
				bot = bot.next;
				bot.prev.next = null;
				bot.prev.prev = null;
				bot.prev = top;
				top.next = bot;
			    }
			else
			    {	
				index.next.prev = index.prev;
				index.prev.next = index.next;
				index.next = null;
				index.prev = null;
			    }
			count--;
			return true;
		    }
	    }
    }
    
public boolean move(int x0, int y0, int x1, int y1)
    {
	if(x0==x1 && y0==y1)
	    return false; // attempt to move to itself
	if(count>1 && !loop)
	    {
		if((top.x==x0 && top.y==y0 && bot.x==x1 && bot.y==y1) ||
		   (top.x==x1 && top.y==y1 && bot.x==x0 && bot.y==y0))
		    {
			top = top.prev;
			top.next.prev = null;

			top.next = bot;
			bot.prev = top;
			loop = true;
			return true;
		    }
	    }
	VertexLink index = bot;
	for(int i=0; i<count; i++)
	    {
		if(index.x == x0 && index.y == y0)
		    {
			index.x = x1;
			index.y = y1;
			return true;
		    }
		index = index.next;
	    }
	return false;
    }

public boolean move_up()
    {
	VertexLink index = bot;
	for(int i=0; i<count; i++)
	    {
		if(index.y < 1)
		    return false;
		index = index.next;
	    }
	index = bot;
	for(int i=0; i<count; i++)
	    {
		index.y--;
		index = index.next;
	    }
	if(loop)
	    bot.y++;
	return true;
    }

public boolean move_down()
    {
	VertexLink index = bot;
	int height_2 = height-2;
	for(int i=0; i<count; i++)
	    {
		if(index.y > height_2)
		    return false;
		index = index.next;
	    }
	index = bot;
	for(int i=0; i<count; i++)
	    {
		index.y++;
		index = index.next;
	    }
	if(loop)
	    bot.y--;
	return true;
    }

public boolean move_left()
    {
	VertexLink index = bot;
	for(int i=0; i<count; i++)
	    {
		if(index.x < 1)
		    return false;
		index = index.next;
	    }
	index = bot;
	for(int i=0; i<count; i++)
	    {
		index.x--;
		index = index.next;
	    }
	if(loop)
	    bot.x++;
	return true;
    }

public boolean move_right()
    {
	VertexLink index = bot;
	int width_2 = width-2;
	for(int i=0; i<count; i++)
	    {
		if(index.x > width_2)
		    return false;
		index = index.next;
	    }
	index = bot;
	for(int i=0; i<count; i++)
	    {
		index.x++;
		index = index.next;
	    }
	if(loop)
	    bot.x--;
	return true;
    }

public void setcolor(Color color_)
    {
	color = color_;
    }

public void setfill(boolean fnf)
    {
	filled = fnf;
    }
    
public void draw()
    {
	for(int i = 0; i<width; i++)
	    for(int j=0; j<height; j++)
		field[i][j] = Color.black;

	VertexLink index = bot;
	for(int i=0; i<count; i++)
	    {
		if(index.next == null)
		    break;
		else
		    drawline(index.x, index.y, index.next.x, index.next.y);
		index = index.next;
	    }
	index = bot;
	Color temp_last;
	if(same(color, Color.red))
	    temp_last = Color.green;
	else
	    temp_last = Color.red;
	
	Color temp_vert;
	if(same(color, Color.blue))
	    temp_vert = Color.green;
	else
	    temp_vert = Color.blue;
	
	for(int i=0; i<count; i++)
	    {
		if(index.next == null)
		    field[index.x][index.y]=temp_last;
		else
		    field[index.x][index.y]=temp_vert;
		index = index.next;
	    }
    }

public void drawline(int xa, int ya, int xb, int yb)
    {
	int dx = Math.abs(xa-xb);
	int dy = Math.abs(ya-yb);

	int twoDy   = 2*dy;
	int twoDx   = 2*dx;
	int twoDyDx = 2*(dy-dx);
	int twoDxDy = 2*(dx-dy);

	int p;
	int x;
	int y;
	int xEnd;
	int yEnd;

	if(dx == 0)
	    {
		if(ya<yb)
		    for(int i=ya; i<=yb; i++)
			field[xa][i] = color;
		else
		    for(int i=yb; i<=ya; i++)
			field[xa][i] = color;
	    }
	else if(dy == 0)
	    {
		if(xa<xb)
		    for(int i=xa; i<=xb; i++)
			field[i][ya] = color;
		else
		    for(int i=xb; i<=xa; i++)
			field[i][ya] = color;
	    }
	else if(dx>dy)
	    {
		if(xa > xb)
		    {
			int temp = xa;
			xa = xb;
			xb = temp;
			temp = ya;
			ya = yb;
			yb = temp;
		    }
		p = 2*dy-dx;
		x = xa;
		y = ya;
		
		if(ya < yb)
		    {
			field[xa][ya] = color;
			for(int i=xa+1; i<=xb; i++)
			    {
				if(p<0)
				    p+=twoDy;
				else
				    {
					y++;
					p+=twoDyDx;
				    }
				field[i][y] = color;
			    }
		    }
		else
		    {
			field[xa][ya] = color;
			for(int i=xa+1; i<=xb; i++)
			    {
				if(p<0)
				    p+=twoDy;
				else
				    {
					y--;
					p+=twoDyDx;
				    }			
				field[i][y] = color;
			    }
		    }
	    }
	else if(dx<dy)
	    {
		if(ya > yb)
		    {
			int temp = ya;
			ya = yb;
			yb = temp;
			temp = xa;
			xa = xb;
			xb = temp;
		    }
		p = 2*dx-dy;
		x = xa;
		y = ya;

		if(xa < xb)
		    {
			field[xa][ya] = color;
			for(int i=ya+1; i<=yb; i++)
			    {
				if(p<0)
				    p+=twoDx;
				else
				    {
					x++;
					p+=twoDxDy;
				    }
				field[x][i] = color;
			    }
		    }
		else
		    {
			field[xa][ya] = color;
			for(int i=ya+1; i<=yb; i++)
			    {
				if(p<0)
				    p+=twoDx;
				else
				    {
					x--;
					p+=twoDxDy;
				    }
				field[x][i] = color;
			    }
		    }
	    }
	else
	    {
		int xstep = (xb-xa)/dx;
		int ystep = (yb-ya)/dy;
		for(int i=0; i<=dx; i++)
		    {
			field[xa][ya] = color;
			xa+=xstep;
			ya+=ystep;
		    }
	    }
    }
    
public void fill(int x, int y)
    {
	if(x<0 || x>=width)
	    return;

	if(y<0 || y>=height)
	    return;
	
	if(!same(field[x][y],Color.black))
	    return;

	field[x][y] = color; 
	fill(x-1, y);
	fill(x, y-1);
	fill(x+1, y);
	fill(x, y+1);
    }

private boolean same(Color a, Color b)
    {
	if(a.getRed()!=b.getRed())
	    return false;
	else if(a.getGreen()!=b.getGreen())
	    return false;
	else if(a.getBlue()!=b.getBlue())
	    return false;
	else
	    return true;
    }
}

