import java.applet.Applet;
import java.awt.*;
public class demoUF extends Applet 
  {
    static final int N = 1000;

    static void clear(Graphics page, Color c)
      { 
        int h = page.getClipRect().height;
        int w = page.getClipRect().width;
        page.setColor(c);
        page.fillRect(0, 0, w, h);
      }
    public void paint(Graphics page)
      {
        int dot = Integer.parseInt(getParameter("dotsize"));
        int V = Integer.parseInt(getParameter("V"));
        int delay = Integer.parseInt(getParameter("delay"));
        double d = Math.sqrt(4.0/V);
        Graph G = new Graph(V, 20*V, d);
        clear(page, Color.lightGray);
        G.paint(page, dot, delay);
      }	    
  }
class Point
  {
    public double x;
    public double y;
 
    Point(double xval, double yval)
      { x = xval; y = yval; }

    public static double distance(Point a, Point b)
      {
        double dx = a.x - b.x, dy = a.y - b.y;
        return Math.sqrt(dx*dx + dy*dy);
      }

  }
class Node
  {
    public int v;
    public Node next;

    Node(int vVal, Node nextVal)
      { v = vVal; next = nextVal; }

  }
class Edge
  {
    public int s, t;

    Edge(int sVal, int tVal)
      { s = sVal; t = tVal; }

  }
class Graph
  {
    int V, E;
    Edge[] edges;
    Node[] adj;
    Point[] p;
    int[] dad;

    int delay, dot;
    Graphics page;

    Graph(int V, int E, double d)
      {
        this.V = V; this.E = 0;
        edges = new Edge[E]; 
        adj = new Node[V]; 
        p = new Point[V]; 
        dad = new int[V]; 
        for (int i = 0; i < V; i++)
          dad[i] = 0;
        for (int i = 0; i < V; i++)
          p[i] = new Point(Math.random(), Math.random());
        for (int i = 0; i < V; i++)
          adj[i] = new Node(i, null);
        for (int i = 0; i < V; i++)
          for (int j = i+1; j < V; j++)
            if (Point.distance(p[i], p[j]) < d)
              { 
                edges[this.E++] = new Edge(i, j);
                adj[j].next = new Node(i, adj[j].next);
                adj[i].next = new Node(j, adj[i].next);
              }
        System.out.println(V + " vertices, " + this.E + " edges.");
      }
    void drawVertex(int i)
      { 
        Point p = this.p[i]; float val = (float) dad[i]/V;
        Color c =  new Color(Color.HSBtoRGB(val, val, val));
        int h = page.getClipRect().height;
        int w = page.getClipRect().width;
        page.setColor(c);
        for (int j = 0; j < delay; j++)
          page.fillOval( (int) (h*p.x)-dot, (int) (w*p.y)-dot, 2*dot, 2*dot);
      }
    void drawEdge(int i, Color c)
      { 
        int s = edges[i].s;
        int t = edges[i].t;
        Point p = this.p[s];
        Point q = this.p[t]; 
        float val = (float) dad[s]/V;
        int h = page.getClipRect().height;
        int w = page.getClipRect().width;
        page.setColor(c);
        for (int j = 0; j < delay; j++)
          page.drawLine( (int) (h*p.x), (int) (w*p.y), 
                         (int) (h*q.x), (int) (w*q.y));
        drawVertex(s); drawVertex(t);
      }
    void paint(Graphics page, int dot, int delay)
      {
        this.page = page; this.dot = dot; this.delay = delay;
        this.dfs();
      }
    void dfs()
      { 
        for (int i = 0; i < V; i++)
          dad[i] = i;
        for (int i = 0; i < V; i++)
          drawVertex(i);
        for (int k = 2; k < E; k++)
          {
            int j = (int) (Math.random()*k);
            Edge t = edges[j]; edges[j] = edges[k]; edges[k] = t;
          }; 

        for (int k = 0; k < E; k++)
          {
            int p = edges[k].s; int q = edges[k].t;
            if (dad[p] == dad[q]) continue; 
            for (int j = 0; j < 100; j++) 
              drawEdge(k, Color.red);
            int t = dad[p];
            for (int i = 0; i < V; i++)
              if (dad[i] == t) 
                { dad[i] = dad[q]; drawVertex(i); }
            drawEdge(k, Color.white);
          }
      }

  }

