Problem: Two players play the following game. Initially, the players have a knife and a rectangular sheet of paper, divided into equal square grid cells of unit size. The players make moves in turn, the player who can't make a move loses. In one move, a player can take the knife and cut the paper along any segment of the grid line (not necessarily from border to border). The part of the paper, that touches the knife at least once, is considered cut. There is one limit not to turn the game into an infinite cycle: each move has to cut the paper, that is the knife has to touch the part of the paper that is not cut before.

Obviously, the game ends when the entire sheet is cut into 1 × 1 blocks. During the game, the pieces of the sheet are not allowed to move. It is also prohibited to cut along the border. The coordinates of the ends of each cut must be integers.

You are given an n × m piece of paper, somebody has already made k cuts there. Your task is to determine who will win if the players start to play on this sheet. You can consider that both players play optimally well. If the first player wins, you also need to find the winning first move.

Input

The first line contains three integers n, m, k (1 ≤ n, m ≤ 109, 0 ≤ k ≤ 105) — the sizes of the piece of paper and the number of cuts. Then follow k lines, each containing 4 integers xbi, ybi, xei, yei (0 ≤ xbi, xei ≤ n, 0 ≤ ybi, yei ≤ m) — the coordinates of the ends of the existing cuts. 

It is guaranteed that each cut has a non-zero length, is either vertical or horizontal and doesn't go along the sheet border.

The cuts may intersect, overlap and even be the same. That is, it is not guaranteed that the cuts were obtained during any correct game.

Output

If the second player wins, print "SECOND". Otherwise, in the first line print "FIRST", and in the second line print any winning move of the first player (the coordinates of the cut ends, follow input format to print them).

Examples

Input

2 1 0


Output

FIRST
1 0 1 1


Input

2 2 4
0 1 2 1
0 1 2 1
1 2 1 0
1 1 1 2


Output

SECOND

Solution (in JAVA):

Solution:
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.AbstractCollection;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import java.util.Arrays;
import java.util.TreeMap;
import java.util.InputMismatchException;
import java.util.ArrayList;
import java.util.AbstractSet;
import java.util.Set;
import java.util.NoSuchElementException;
import java.util.TreeSet;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author ogiekako
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		MyScanner in = new MyScanner(inputStream);
		MyPrintWriter out = new MyPrintWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    class Cut{
        int axis;
        IntervalSet intervalSet;

        public Cut(Integer axis, IntervalSet intervalSet) {
            this.axis = axis;
            this.intervalSet = intervalSet;
        }
    }
    int height, width;
    Map<Integer, IntervalSet> xSet = new TreeMap<Integer, IntervalSet>();
    Map<Integer, IntervalSet> ySet = new TreeMap<Integer, IntervalSet>();
    List<Cut> xCuts = new ArrayList<Cut>();
    List<Cut> yCuts = new ArrayList<Cut>();
    public void solve(int testNumber, MyScanner in, MyPrintWriter out) {
        height = in.nextInt();
        width = in.nextInt();
        int k = in.nextInt();
        for (int i = 0; i < k; i++){
            add(in.nextInt(), in.nextInt(), in.nextInt(), in.nextInt());
        }
        for(Map.Entry<Integer, IntervalSet> entry : xSet.entrySet())xCuts.add(new Cut(entry.getKey(),entry.getValue()));
        for(Map.Entry<Integer, IntervalSet> entry : ySet.entrySet())yCuts.add(new Cut(entry.getKey(),entry.getValue()));
        int xor = calcXor();
        if(xor == 0){
            out.println("SECOND");
            return;
        }
        out.println("FIRST");

        calcMove(xor, out);
    }

    private void calcMove(int xor, MyPrintWriter out) {
        boolean ok = calcMove(xor, height, width, xCuts, true, out);
        if(!ok)calcMove(xor, width, height, yCuts, false, out);
    }

    private boolean calcMove(int xor, int height, int width, List<Cut> xCuts, boolean isX, MyPrintWriter out) {
        int empty = height - 1 - xCuts.size();
        if(empty > 0 && move(xor, width) > 0){
            IntervalSet set = new IntervalSet();
            set.add(new Interval(0,width));
            Interval cut = calcCut(move(xor, width), set);
            print(out, firstEmpty(xCuts), cut, isX);
            return true;
        }
        for(Cut cut : xCuts){
            IntervalSet all = new IntervalSet();
            all.add(Interval.of(0, width));
            IntervalSet rests = cut.intervalSet.xored(all);
            int pile = (int) rests.cardinality();
            if(move(xor, pile) > 0){
                Interval iv = calcCut(move(xor,pile), rests);
                print(out, cut.axis, iv, isX);
                return true;
            }
        }
        return false;
    }

    private Interval calcCut(int cut, IntervalSet rest) {
        for(Interval i : rest.toArray()){
            long len = i.length();
            if(cut <= len){
                return Interval.of(0, i.left + cut);
            }
            cut -= len;
        }
        throw new AssertionError();
    }

    private void print(MyPrintWriter out, int o, Interval interval, boolean isX) {
        if(isX)out.printFormat("%d %d %d %d\n", o, interval.left, o, interval.right);
        else out.printFormat("%d %d %d %d\n", interval.left, o, interval.right, o);
    }

    private int firstEmpty(List<Cut> cuts) {
        for(int i=1;;i++){
            if(i > cuts.size() || cuts.get(i-1).axis != i)return i;
        }
    }

    private int move(int xor, int pile) {
        xor ^= pile;
        if(xor < pile)return pile - xor;
        return -1;
    }

    private int calcXor() {
        return calcXor(height, width, xCuts) ^ calcXor(width, height, yCuts);
    }

    private int calcXor(int height, int width, List<Cut> xCuts) {
        int empty = height - 1 - xCuts.size();
        int res = 0;
        if((empty&1)==1)res ^= width;
        for(Cut cut : xCuts){
            res ^= calcXor(width, cut.intervalSet);
        }
        return res;
    }

    private int calcXor(int length, IntervalSet intervalSet) {
        return (int) (length - intervalSet.cardinality());
    }

    private void add(int xb, int yb, int xe, int ye) {
        if(xb==xe){
            put(xSet, xb, Interval.of(yb, ye));
        }else{
            put(ySet, yb, Interval.of(xb,xe));
        }
    }

    private void put(Map<Integer, IntervalSet> map, int o, Interval interval) {
        if(!map.containsKey(o))map.put(o, new IntervalSet());
        map.get(o).add(interval);
    }
}

class IntervalSet {
    TreeSet<Interval> set = new TreeSet<Interval>();
    public void add(Interval interval) {
        set.add(interval);
    }
    public long cardinality(){
        union();
        long res = 0;
        for(Interval i:set){
            res += i.length();
        }
        return res;
    }

    private void union() {
        if(set.isEmpty())return;
        Interval[] is = set.toArray(new Interval[set.size()]);
        set.clear();
        Interval current = is[0];
        for(int i=1;i<is.length;i++){
            if(current.canUnion(is[i])){
                current = current.union(is[i]);
            }else{
                set.add(current);
                current = is[i];
            }
        }
        set.add(current);
    }

    public String toString() {
        return "IntervalSet{" +
                "set=" + set +
                '}';
    }

    public Interval[] toArray() {
        union();
        return set.toArray(new Interval[set.size()]);
    }

    /**
     * n log n
     */
    public IntervalSet xored(IntervalSet other) {
        Interval[] is = toArray(), js = other.toArray();
        int lenI = is.length, lenJ = js.length;
        long from=0, to=0;
        int type = 0;
        int iPtr = 0, jPtr = 0;
        IntervalSet res = new IntervalSet();
        while(iPtr<lenI || jPtr<lenJ){
            if(type == 0){
                if(jPtr>=lenJ || iPtr<lenI && is[iPtr].left < js[jPtr].right){
                    type = 1;
                    from = is[iPtr].left;
                    to = is[iPtr++].right;
                }else{
                    type = 2;
                    from = js[jPtr].left;
                    to = js[jPtr++].right;
                }
            }
            else if(type == 1){// i
                if(jPtr < lenJ && js[jPtr].left < to){
                    res.add(new Interval(from, js[jPtr].left));
                    if(js[jPtr].right < to){
                        from = js[jPtr].right;
                    }else{
                        from = to;
                        to = js[jPtr].right;
                        type = 2;
                    }
                    jPtr++;
                }else{
                    res.add(new Interval(from, to));
                    type = 0;
                }
            }else {// j
                if(iPtr < lenI && is[iPtr].left < to){
                    res.add(new Interval(from, is[iPtr].left));
                    if(is[iPtr].right < to){
                        from = is[iPtr].right;
                    }else{
                        from = to;
                        to = is[iPtr].right;
                        type = 1;
                    }
                    iPtr++;
                }else{
                    res.add(new Interval(from, to));
                    type = 0;
                }
            }
        }
        res.add(new Interval(from, to));
        return res;

//        TreeSet<Long> pointSet = new TreeSet<Long>();
//        for(Interval i : is){
//            pointSet.add(i.left);
//            pointSet.add(i.right);
//        }
//        for(Interval j : js){
//            pointSet.add(j.left);
//            pointSet.add(j.right);
//        }
//        long[] points = Cast.toLongArray(pointSet);
//        boolean[] xor = new boolean[points.length];
//        for(Interval i : is){
//            int l = Arrays.binarySearch(points, i.left);
//            int r = Arrays.binarySearch(points, i.right);
//            for (int j = l; j < r; j++)xor[j] ^= true;
//        }
//        for(Interval i : js) {
//            int l = Arrays.binarySearch(points, i.left);
//            int r = Arrays.binarySearch(points, i.right);
//            for (int j = l; j < r; j++) xor[j] ^= true;
//        }
//        IntervalSet res = new IntervalSet();
//        for (int i = 0; i < points.length; ){
//            if(xor[i]){
//                int j = i;
//                while(xor[j])j++;
//                res.add(Interval.of(points[i], points[j]));
//                i=j;
//            }else i++;
//        }
//        return res;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        IntervalSet that = (IntervalSet) o;

        return set.equals(that.set);

    }

    public int hashCode() {
        return set.hashCode();
    }
}

class MyScanner {
    private final InputStream in;

    public MyScanner(InputStream in) {
        this.in = in;
    }

    int bufLen;
    int bufPtr;
    byte[] buf = new byte[1024];

    public int read() {
        if (bufLen == -1)
            throw new InputMismatchException();
        if (bufPtr >= bufLen) {
            bufPtr = 0;
            try {
                bufLen = in.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (bufLen <= 0)
                return -1;
        }
        return buf[bufPtr++];
    }

    public int nextInt() {
        int c = read();
        if (c == -1) throw new NoSuchElementException();
        while (c != '-' && (c < '0' || '9' < c)) {
            c = read();
            if (c == -1) throw new NoSuchElementException();
        }
        if (c == '-') return -nextInt();
        int res = 0;
        do {
            res *= 10;
            res += c - '0';
            c = read();
        } while ('0' <= c && c <= '9');
        return res;
    }


    }

class MyPrintWriter {
    PrintWriter out;

    public MyPrintWriter(OutputStream outputStream) {
        out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public MyPrintWriter(Writer writer) {
        out = new PrintWriter(writer);
    }

    public void println(Object... os) {
        for (int i = 0; i < os.length - 1; i++) {
            out.print(os[i]);
            out.print(' ');
        }
        out.println(os[os.length - 1]);
    }

    public void close() {
        out.close();
    }

    public void printFormat(String format, Object... args) {
        out.printf(format,args);
    }

}

class Interval implements Comparable<Interval>{
    public final long left,right;

    /**
     * if left > right, right and left are swapped.
     * @param left - left (inclusive)
     * @param right - right (exclusive)
     */
    public Interval(long left, long right) {// [left, right)
        if(left > right){long tmp = left; left = right; right = tmp;}
        this.left = left;
        this.right = right;
    }

    public int compareTo(Interval o) {
        if(left != o.left)return IntegerUtils.compare(left, o.left);
        return IntegerUtils.compare(right, o.right);
    }

    public long length() {
        return right - left;
    }

    /**
     * have (maybe empty) intersection
     * @param interval
     * @return
     */
    public boolean canUnion(Interval interval) {
        long minRight = Math.min(right, interval.right);
        long maxLeft = Math.max(left,interval.left);
        return minRight >= maxLeft;
    }

    /*
     * throws exception when two intervals are distinct.
     */
    public Interval union(Interval interval) {
        if(!canUnion(interval))throw new IllegalArgumentException();
        return new Interval(Math.min(left,interval.left),Math.max(right,interval.right));
    }

    public static Interval of(long left, long right) {
        return new Interval(left, right);
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Interval interval = (Interval) o;

        return left == interval.left && right == interval.right;

    }

    public int hashCode() {
        int result = (int) (left ^ (left >>> 32));
        result = 31 * result + (int) (right ^ (right >>> 32));
        return result;
    }

    public String toString() {
        return "Interval{" +
                "left=" + left +
                ", right=" + right +
                '}';
    }
}

class IntegerUtils {

    public static int compare(long o1, long o2) {
        return o1 < o2 ? -1 : o1 > o2 ? 1 : 0;
    }

    }