/* The Computer Language Shootout
   http://shootout.alioth.debian.org/

   contributed by Keenan Tims
   modified by Michael Barker
*/


public class chameneos {

    private MeetingPlace mp;

    public static final Colour[] COLOURS = { Colour.BLUE, Colour.RED, Colour.YELLOW, Colour.BLUE };

    private Creature[] creatures = new Creature[COLOURS.length];

    public enum Colour {
        RED, BLUE, YELLOW, FADED
    }

    public class Creature extends Thread {

        private MeetingPlace mp;
        private Colour colour;
        private int met = 0;
        private Colour other;

        public Creature(Colour c, MeetingPlace mp) {
            this.colour = c;
            this.mp = mp;
        }

        public void run() {
            try {
                while (colour != Colour.FADED) {
                    mp.meet(this);
                    if (other == Colour.FADED)
                        colour = Colour.FADED;
                    else {
                        met++;
                        colour = complement(other);
                    }
                }
            } catch (InterruptedException e) {
                // Let the thread exit.
            }
        }

        private Colour complement(Colour other) {
            if (colour == other)
                return colour;
            switch (colour) {
            case BLUE:
                return other == Colour.RED ? Colour.YELLOW : Colour.RED;
            case RED:
                return other == Colour.BLUE ? Colour.YELLOW : Colour.BLUE;
            case YELLOW:
                return other == Colour.BLUE ? Colour.RED : Colour.BLUE;
            default:
                return colour;
            }
        }

        public int getCreaturesMet() {
            return met;
        }

        public Colour getColour() {
            return colour;
        }

        public void setOther(Colour other) throws InterruptedException {
            this.other = other;
        }
    }

    public class MeetingPlace {

        int n;

        public MeetingPlace(int n) {
            this.n = n;
        }

        Creature other = null;
        public void meet(Creature c) throws InterruptedException {

            synchronized (this) {
                if (n > 0) {
                    if (other == null) {
                        other = c;
                        this.wait();
                    } else {
                        other.setOther(c.getColour());
                        c.setOther(other.getColour());
                        other = null;
                        n--;
                        this.notify();
                    }
                } else {
                    c.setOther(Colour.FADED);
                }
            }
        }
    }

    public chameneos(int n) throws InterruptedException {
        int meetings = 0;
        mp = new MeetingPlace(n);

        for (int i = 0; i < COLOURS.length; i++) {
            creatures[i] = new Creature(COLOURS[i], mp);
            creatures[i].start();
        }

        // wait for all threads to complete
        for (int i = 0; i < COLOURS.length; i++)
            creatures[i].join();

        // sum all the meetings
        for (int i = 0; i < COLOURS.length; i++) {
            meetings += creatures[i].getCreaturesMet();
        }

        System.out.println(meetings);
    }

    public static void main(String[] args) throws Exception {
        if (args.length < 1)
            throw new IllegalArgumentException();
        new chameneos(Integer.parseInt(args[0]));
    }
}
