#include <bits/stdc++.h>
#define range(i, a, n) for(int (i) = (a); (i) < (n); (i)++)
#define rep(i, n) for(int (i) = 0; (i) < (n); (i)++)
using namespace std;

using pii = pair<int, int>;
#define fst first
#define snd second

struct UnionFind {
    vector<int> data;
    vector<int> diff_w;
    UnionFind(int size) : data(size, -1), diff_w(size) { }

    bool unionSet(int x, int y, int w) {
        pii xx = _root(x), yy = _root(y);
        x = xx.fst, y = yy.fst;
        if (x != y) {
            if (data[y] < data[x]) swap(x, y), swap(xx, yy), w *= -1;
            data[x] += data[y]; data[y] = x;
            diff_w[y] = xx.snd - yy.snd + w;
        }
        return x != y;
    }
    bool findSet(int x, int y) {
        return root(x) == root(y);
    }
    int root(int x){
        return _root(x).fst;
    }
    int diff(int x, int y){
        root(x);
        root(y);

        return diff_w[y] - diff_w[x];
    }
    pii _root(int x) {
        pii ret;

        if(data[x] < 0){
            ret = pii(x, diff_w[x]);
        }
        else {
            ret = _root(data[x]);
            ret.snd += diff_w[x];

            data[x]    = ret.fst;
            diff_w[x]  = ret.snd;
        }

        return ret;
    }
    int size(int x) {
        return -data[root(x)];
    }
};

int main(void){
    for(int n, m; cin >> n >> m, n;){
        UnionFind uf(n);

        rep(_, m){
            char op; cin >> op;

            if(op == '!'){
                int a, b, w; cin >> a >> b >> w;
                a--, b--;
                uf.unionSet(a, b, w);
            }
            else {
                int a, b; cin >> a >> b;
                a--, b--;
                if(not uf.findSet(a, b)) cout << "UNKNOWN" << endl;
                else cout << uf.diff(a, b) << endl;
            }
        }
    }

    return 0;
}