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

struct RootPath {
    Node node;
    int value;
}

class Node {
    int index;
    Edge rootEdge;
    RootPath root() {
        if (rootEdge) {
            //writeln("root:   ", [this.toHash, rootEdge.to.toHash]);
            RootPath p = rootEdge.to.root;
            p.value += rootEdge.value;
            if (p.node != rootEdge.to) {
                rootEdge = new Edge(this, p.node, p.value);
            }
            return p;
        } else {
            return RootPath(this, 0);
        }
    }
}

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

void main() {
    int N, Q; readf("%d %d\n", &N, &Q);
    Node[] graph = new Node[N];
    foreach (int i, ref n; graph) {
        n = new Node;
        n.index = i + 1;
    }
    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") {
            //writeln("before: ", [graph[A].toHash, graph[B].toHash]);
            int C = input[3].to!int;
            if (graph[A].root.node == graph[B].root.node) {
                auto curA = graph[A],
                     curB = graph[B];
                auto nextA = new Node,
                     nextB = new Node;
                nextA.rootEdge = new Edge(nextA, curA, -C);
                nextB.rootEdge = new Edge(nextB, curB, -C);
                graph[A] = nextA;
                graph[B] = nextB;
                continue;
            }
            if (graph[A].rootEdge) {
                if (graph[B].rootEdge) {
                    auto curA = graph[A],
                         curB = graph[B];
                    auto curAO = curA.root.node,
                         curBO = curB.root.node;
                    auto nextA = new Node,
                         nextB = new Node;
                    int xa = curA.root.value,
                        xb = curB.root.value;
                    curAO.rootEdge = new Edge(curAO, curBO, -xa + xb + C);
                    nextA.rootEdge = new Edge(nextA, curBO, xb);
                    nextB.rootEdge = new Edge(nextB, curBO, xb - C);
                    graph[A] = nextA;
                    graph[B] = nextB;
                } else {
                    auto curA = graph[A],
                         curB = graph[B];
                    auto curO = curA.root.node;
                    int x = curA.root.value;
                    auto nextA = new Node,
                         nextB = new Node;
                    curB.rootEdge = new Edge(curB, nextB, C);
                    nextA.rootEdge = new Edge(nextA, curO, x - C);
                    nextB.rootEdge = new Edge(nextB, curO, x - 2 * C);
                    graph[A] = nextA;
                    graph[B] = nextB;
                }
            } else {
                if (graph[B].rootEdge) {
                    auto curA = graph[A],
                         curB = graph[B];
                    auto curO = curB.root.node;
                    int x = curB.root.value;
                    auto nextA = new Node,
                         nextB = new Node;
                    curA.rootEdge = new Edge(curA, nextA, C);
                    nextA.rootEdge = new Edge(nextA, curO, x);
                    nextB.rootEdge = new Edge(nextB, curO, x - C);
                    graph[A] = nextA;
                    graph[B] = nextB;
                } else {
                    auto curA = graph[A],
                         curB = graph[B];
                    auto nextA = new Node,
                         nextB = new Node;
                    curA.rootEdge = new Edge(curA, nextA, C);
                    curB.rootEdge = new Edge(curB, nextB, C);
                    nextA.rootEdge = new Edge(nextA, nextB, C);
                    graph[A] = nextA;
                    graph[B] = nextB;
                }
            }
            //writeln("after:  ", [graph[A].toHash, graph[B].toHash]);
        } else {
            RootPath a = graph[A].root,
                     b = graph[B].root;
            if (a.node == b.node) {
                (a.value - b.value).writeln;
            } else {
                "WARNING".writeln;
            }
        }
    }
}

Measured memory_bytes: 12508