Problem: Levko loves sports pathfinding competitions in his city very much. In order to boost his performance, Levko spends his spare time practicing. The practice is a game.

The city consists of n intersections connected by m + k directed roads. Two or more roads can connect the same pair of intersections. Besides, there can be roads leading from an intersection to itself. 

Levko and Zenyk are playing a game. First Levko stands on intersection s1, and Zenyk stands on intersection s2. They both want to get to intersection f. The person who does it quicker wins. If they get there at the same time, the game ends with a draw. By agreement both players start simultaneously and move with the same speed.

Levko wants to win very much. He knows the lengths of all the roads in the city. Also he knows that he can change the lengths of some roads (there are k such roads at all) if he pays the government. So, the government can change the length of the i-th road to any integer value in the segment [li, ri] (both borders inclusive). Levko wondered if he can reconstruct the roads so as to win the game and whether he can hope for the draw if he cannot win.

You should consider that both players play optimally well. It is guaranteed that we can get from intersections s1 and s2 to intersection f. 

Input

The first line contains three integers n, m and k (1 ≤ n, m ≤ 104, 1 ≤ k ≤ 100). The second line contains three integers s1, s2 and f (1 ≤ s1, s2, f ≤ n).

The next m lines contains the descriptions of the roads that cannot be changed by Levko. Each line contains three integers ai, bi and ci (1 ≤ ai, bi ≤ n, 1 ≤ ci ≤ 109), representing a road from intersection ai to intersection bi of length ci.

The next k lines contains the descriptions of the roads that can be changed by Levko. Each line contains four integers ai, bi, li and ri (1 ≤ ai, bi ≤ n, 1 ≤ li ≤ ri ≤ 109), representing a road from intersection ai to intersection bi, Levko can set the road's length within limits [li, ri].

Consider all intersections numbered from 1 to n. It is guaranteed that you can get from intersections s1 and s2 to intersection f.

Output

In the first line print string "WIN" (without the quotes) if Levko can win this game, string "DRAW" (without the quotes) if Levko can end the game with a draw and "LOSE" (without the quotes) if he loses for sure.

If the answer is "WIN" or "DRAW", then print on the second line k space-separated integers — the length of the roads Levko sets in the order they occur in the input.

Examples

Input

4 1 3
1 3 4
3 2 2
1 2 1 3
2 4 1 3
3 4 1 3


Output

WIN
1 1 3 

Input

4 1 3
1 3 4
3 2 2
1 2 1 3
2 4 1 3
3 4 1 2


Output

DRAW
1 1 2 

Input

5 4 2
1 2 5
1 3 3
1 4 4
2 3 2
2 4 3
3 5 1 5
4 5 4 7


Output

LOSE

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.io.IOException;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Egor Kulikov (egor@egork.net)
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		TaskE solver = new TaskE();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskE {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
		int count = in.readInt();
		int ordinaryRoadCount = in.readInt();
		int specialRoadCount = in.readInt();
		int ourStart = in.readInt() - 1;
		int villainStart = in.readInt() - 1;
		int finish = in.readInt() - 1;
		int[] ordinaryFrom = new int[ordinaryRoadCount];
		int[] ordinaryTo = new int[ordinaryRoadCount];
		int[] ordinaryDistance = new int[ordinaryRoadCount];
		IOUtils.readIntArrays(in, ordinaryFrom, ordinaryTo, ordinaryDistance);
		int[] specialFrom = new int[specialRoadCount];
		int[] specialTo = new int[specialRoadCount];
		int[] specialDistanceFrom = new int[specialRoadCount];
		int[] specialDistanceTo = new int[specialRoadCount];
		IOUtils.readIntArrays(in, specialFrom, specialTo, specialDistanceFrom, specialDistanceTo);
		MiscUtils.decreaseByOne(ordinaryFrom, ordinaryTo, specialFrom, specialTo);
		if (ourStart == villainStart) {
			out.printLine("DRAW");
			out.printLine(specialDistanceFrom);
			return;
		}
		Graph graph = new Graph(count);
		for (int i = 0; i < ordinaryRoadCount; i++)
			graph.addSimpleEdge(ordinaryFrom[i], ordinaryTo[i]);
		for (int i = 0; i < specialRoadCount; i++)
			graph.addSimpleEdge(specialFrom[i], specialTo[i]);
		boolean[] can = solve(count, ordinaryRoadCount, specialRoadCount, ourStart, villainStart, finish, 1, graph, ordinaryDistance, specialDistanceFrom, specialDistanceTo);
		if (can == null) {
			can = solve(count, ordinaryRoadCount, specialRoadCount, ourStart, villainStart, finish, 0, graph, ordinaryDistance, specialDistanceFrom, specialDistanceTo);
			if (can == null) {
				out.printLine("LOSE");
				return;
			}
			out.printLine("DRAW");
		} else
			out.printLine("WIN");
		int[] distance = new int[specialRoadCount];
		for (int i = 0; i < specialRoadCount; i++) {
			if (can[i])
				distance[i] = specialDistanceFrom[i];
			else
				distance[i] = specialDistanceTo[i];
		}
		out.printLine(distance);
    }

	private boolean[] solve(int count, int ordinaryRoadCount, int specialRoadCount, int ourStart, int villainStart, int finish, int gap, Graph graph, int[] ordinaryDistance, int[] specialDistanceFrom, int[] specialDistanceTo) {
		final long[] distance = new long[count];
		Arrays.fill(distance, Long.MAX_VALUE);
		Heap heap = new Heap(new IntComparator() {
			public int compare(int first, int second) {
				return Long.compare(distance[first], distance[second]);
			}
		}, count);
		int[] winner = new int[count];
		distance[ourStart] = gap;
		winner[ourStart] = 1;
		heap.add(ourStart);
		distance[villainStart] = 0;
		winner[villainStart] = -1;
		heap.add(villainStart);
		int[] last = new int[count];
		Arrays.fill(last, -1);
		while (!heap.isEmpty()) {
			int current = heap.poll();
			int[] specialDistance;
			if (winner[current] == 1)
				specialDistance = specialDistanceFrom;
			else
				specialDistance = specialDistanceTo;
			for (int i = graph.firstOutbound(current); i != -1; i = graph.nextOutbound(i)) {
				int destination = graph.destination(i);
				long total = distance[current];
				if (i < ordinaryRoadCount)
					total += ordinaryDistance[i];
				else
					total += specialDistance[i - ordinaryRoadCount];
				if (total < distance[destination] || total == distance[destination] && winner[current] == 1) {
					distance[destination] = total;
					if (winner[destination] == 0)
						heap.add(destination);
					else
						heap.shiftUp(heap.getIndex(destination));
					winner[destination] = winner[current];
					last[destination] = i;
				}
			}
		}
		if (winner[finish] != 1)
			return null;
		boolean[] result = new boolean[specialRoadCount];
		while (finish != ourStart) {
			if (last[finish] >= ordinaryRoadCount)
				result[last[finish] - ordinaryRoadCount] = true;
			finish = graph.source(last[finish]);
		}
		return result;
	}
}

class InputReader {

	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(InputStream stream) {
		this.stream = stream;
	}

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

	public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}

	public OutputWriter(Writer writer) {
		this.writer = new PrintWriter(writer);
	}

	public void print(Object...objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}

    public void print(int[] array) {
        for (int i = 0; i < array.length; i++) {
            if (i != 0)
                writer.print(' ');
            writer.print(array[i]);
        }
    }

    public void printLine(int[] array) {
        print(array);
        writer.println();
    }

    public void printLine(Object...objects) {
		print(objects);
		writer.println();
	}

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

	}

class IOUtils {

	public static void readIntArrays(InputReader in, int[]... arrays) {
		for (int i = 0; i < arrays[0].length; i++) {
			for (int j = 0; j < arrays.length; j++)
				arrays[j][i] = in.readInt();
		}
	}

	}

class MiscUtils {

    public static void decreaseByOne(int[]...arrays) {
		for (int[] array : arrays) {
			for (int i = 0; i < array.length; i++)
				array[i]--;
		}
	}

	}

class Graph {
	public static final int REMOVED_BIT = 0;

	protected int vertexCount;
	protected int edgeCount;

	private int[] firstOutbound;
	private int[] firstInbound;

	private Edge[] edges;
	private int[] nextInbound;
	private int[] nextOutbound;
	private int[] from;
	private int[] to;
	private long[] weight;
	private long[] capacity;
	private int[] reverseEdge;
	private int[] flags;

	public Graph(int vertexCount) {
		this(vertexCount, vertexCount);
	}

	public Graph(int vertexCount, int edgeCapacity) {
		this.vertexCount = vertexCount;
		firstOutbound = new int[vertexCount];
		Arrays.fill(firstOutbound, -1);

		from = new int[edgeCapacity];
		to = new int[edgeCapacity];
		nextOutbound = new int[edgeCapacity];
		flags = new int[edgeCapacity];
	}

	public int addEdge(int fromID, int toID, long weight, long capacity, int reverseEdge) {
		ensureEdgeCapacity(edgeCount + 1);
		if (firstOutbound[fromID] != -1)
			nextOutbound[edgeCount] = firstOutbound[fromID];
		else
			nextOutbound[edgeCount] = -1;
		firstOutbound[fromID] = edgeCount;
		if (firstInbound != null) {
			if (firstInbound[toID] != -1)
				nextInbound[edgeCount] = firstInbound[toID];
			else
				nextInbound[edgeCount] = -1;
			firstInbound[toID] = edgeCount;
		}
		this.from[edgeCount] = fromID;
		this.to[edgeCount] = toID;
		if (capacity != 0) {
			if (this.capacity == null)
				this.capacity = new long[from.length];
			this.capacity[edgeCount] = capacity;
		}
		if (weight != 0) {
			if (this.weight == null)
				this.weight = new long[from.length];
			this.weight[edgeCount] = weight;
		}
		if (reverseEdge != -1) {
			if (this.reverseEdge == null) {
				this.reverseEdge = new int[from.length];
				Arrays.fill(this.reverseEdge, 0, edgeCount, -1);
			}
			this.reverseEdge[edgeCount] = reverseEdge;
		}
		if (edges != null)
			edges[edgeCount] = createEdge(edgeCount);
		return edgeCount++;
	}

	protected final GraphEdge createEdge(int id) {
		return new GraphEdge(id);
	}

	public final int addFlowWeightedEdge(int from, int to, long weight, long capacity) {
		if (capacity == 0) {
			return addEdge(from, to, weight, 0, -1);
		} else {
			int lastEdgeCount = edgeCount;
			addEdge(to, from, -weight, 0, lastEdgeCount + entriesPerEdge());
			return addEdge(from, to, weight, capacity, lastEdgeCount);
		}
	}

	protected int entriesPerEdge() {
		return 1;
	}

	public final int addWeightedEdge(int from, int to, long weight) {
		return addFlowWeightedEdge(from, to, weight, 0);
	}

	public final int addSimpleEdge(int from, int to) {
		return addWeightedEdge(from, to, 0);
	}

	public final int firstOutbound(int vertex) {
		int id = firstOutbound[vertex];
		while (id != -1 && isRemoved(id))
			id = nextOutbound[id];
		return id;
	}

	public final int nextOutbound(int id) {
		id = nextOutbound[id];
		while (id != -1 && isRemoved(id))
			id = nextOutbound[id];
		return id;
	}

	public final int source(int id) {
		return from[id];
	}

	public final int destination(int id) {
		return to[id];
	}

	public final boolean flag(int id, int bit) {
		return (flags[id] >> bit & 1) != 0;
	}

	public final boolean isRemoved(int id) {
		return flag(id, REMOVED_BIT);
	}

	protected void ensureEdgeCapacity(int size) {
		if (from.length < size) {
			int newSize = Math.max(size, 2 * from.length);
			if (edges != null)
				edges = resize(edges, newSize);
			from = resize(from, newSize);
			to = resize(to, newSize);
			nextOutbound = resize(nextOutbound, newSize);
			if (nextInbound != null)
				nextInbound = resize(nextInbound, newSize);
			if (weight != null)
				weight = resize(weight, newSize);
			if (capacity != null)
				capacity = resize(capacity, newSize);
			if (reverseEdge != null)
				reverseEdge = resize(reverseEdge, newSize);
			flags = resize(flags, newSize);
		}
	}

	protected final int[] resize(int[] array, int size) {
		int[] newArray = new int[size];
		System.arraycopy(array, 0, newArray, 0, array.length);
		return newArray;
	}

	private long[] resize(long[] array, int size) {
		long[] newArray = new long[size];
		System.arraycopy(array, 0, newArray, 0, array.length);
		return newArray;
	}

	private Edge[] resize(Edge[] array, int size) {
		Edge[] newArray = new Edge[size];
		System.arraycopy(array, 0, newArray, 0, array.length);
		return newArray;
	}

	protected class GraphEdge implements Edge {
		protected int id;

		protected GraphEdge(int id) {
			this.id = id;
		}

		}

	}

class Heap {
	private IntComparator comparator;
	private int size = 0;
	private int[] elements;
	private int[] at;

	public Heap(int maxElement) {
		this(10, maxElement);
	}

	public Heap(IntComparator comparator, int maxElement) {
		this(10, comparator, maxElement);
	}

	public Heap(int capacity, int maxElement) {
		this(capacity, IntComparator.DEFAULT, maxElement);
	}

	public Heap(int capacity, IntComparator comparator, int maxElement) {
		this.comparator = comparator;
		elements = new int[capacity];
		at = new int[maxElement];
		Arrays.fill(at, -1);
	}

	public boolean isEmpty() {
		return size == 0;
	}

	public int add(int element) {
		ensureCapacity(size + 1);
		elements[size] = element;
		at[element] = size;
		shiftUp(size++);
		return at[element];
	}

	public void shiftUp(int index) {
//		if (index < 0 || index >= size)
//			throw new IllegalArgumentException();
		int value = elements[index];
		while (index != 0) {
			int parent = (index - 1) >>> 1;
			int parentValue = elements[parent];
			if (comparator.compare(parentValue, value) <= 0) {
				elements[index] = value;
				at[value] = index;
				return;
			}
			elements[index] = parentValue;
			at[parentValue] = index;
			index = parent;
		}
		elements[0] = value;
		at[value] = 0;
	}

	public void shiftDown(int index) {
		if (index < 0 || index >= size)
			throw new IllegalArgumentException();
		while (true) {
			int child = (index << 1) + 1;
			if (child >= size)
				return;
			if (child + 1 < size && comparator.compare(elements[child], elements[child + 1]) > 0)
				child++;
			if (comparator.compare(elements[index], elements[child]) <= 0)
				return;
			swap(index, child);
			index = child;
		}
	}

	public int getIndex(int element) {
		return at[element];
	}

	private void swap(int first, int second) {
		int temp = elements[first];
		elements[first] = elements[second];
		elements[second] = temp;
		at[elements[first]] = first;
		at[elements[second]] = second;
	}

	private void ensureCapacity(int size) {
		if (elements.length < size) {
			int[] oldElements = elements;
			elements = new int[Math.max(2 * elements.length, size)];
			System.arraycopy(oldElements, 0, elements, 0, this.size);
		}
	}

	public int poll() {
		if (isEmpty())
			throw new IndexOutOfBoundsException();
		int result = elements[0];
		at[result] = -1;
		if (size == 1) {
			size = 0;
			return result;
		}
		elements[0] = elements[--size];
		at[elements[0]] = 0;
		shiftDown(0);
		return result;
	}

    }

interface IntComparator {
    public static final IntComparator DEFAULT = new IntComparator() {
        public int compare(int first, int second) {
            if (first < second)
                return -1;
            if (first > second)
                return 1;
            return 0;
        }
    };

	public int compare(int first, int second);
}

interface Edge {
	}