import std.stdio;
import std.string;
import std.conv;
import std.range;
import std.array;
import std.algorithm;

class Node {
    Edge[] edges;
}

class Edge {
    Node from, to;
    int value;
    this(Node from, Node to, int value) {
        this.from = from;
        this.to = to;
        this.value = value;
    }
}

struct MaybeInt {
    bool f;
    int value;
    this(bool f, int value = 0) {
        this.f = f;
        this.value = value;
    }
}

MaybeInt search(Node from, Node to, bool[Node] used) {
    if (from == to) return MaybeInt(true, 0);
    used[from] = true;
    foreach (edge; from.edges) {
        Node next = edge.to;
        if (used.get(next, false)) continue;
        MaybeInt result = search(next, to, used);
        if (result.f) {
            return MaybeInt(true, result.value + edge.value);
        }
    }
    return MaybeInt(false);
}

void main() {
    int N, Q; readf("%d %d\n", &N, &Q);
    Node[] graph = new Node[N];
    foreach (ref n; graph) n = new Node;
    foreach (_; 0 .. Q) {
        auto input = readln.chomp.split(" ");
        string cmd = input[0];
        int A = input[1].to!int - 1,
            B = input[2].to!int - 1;
        if (cmd == "IN") {
            int C = input[3].to!int;
            Node a = new Node; a.edges ~= new Edge(a, graph[A], -C);
            graph[A].edges ~= new Edge(graph[A], a, C);
            graph[A] = a;
    
            Node b = new Node; b.edges ~= new Edge(b, graph[B], -C);
            graph[B].edges ~= new Edge(graph[B], b, C);
            graph[B] = b;

            graph[A].edges ~= new Edge(graph[A], graph[B], C);
            graph[B].edges ~= new Edge(graph[B], graph[A], -C);
        } else {
            MaybeInt result = search(graph[A], graph[B], (bool[Node]).init);
            (result.f ? result.value.to!string : "WARNING").writeln;
        }
    }
}