#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

//BEGIN CUT HERE
//重み付きUnion_find
//typename Tには重みの型を入力する
template <typename T>
class Potential_UF{
public:
    explicit Potential_UF(int n):size(n){
        Rank.resize(static_cast<unsigned long>(n), 0);
        parent.resize(static_cast<unsigned long>(n));
        weight.resize(n,unity);
        cont.resize(static_cast<unsigned long>(n), 1);
        for(int i=0;i<size;i++){parent[i]=i;}
    }

    //xの属しているグループの番号を返します
    int find(int x) {
        if (parent[x] == x)return x;
        else {
            int r = find(parent[x]);
            weight[x] += weight[parent[x]];
            return parent[x] = r;
        }
    }

    //xにつけられている重みを返します
    T get_weight(int x){
        find(x);
        return weight[x];
    }

    //xとyの重みの差を返します
    //weight(y)-weight(x)
    T diff(int x,int y){
        return get_weight(y)-get_weight(x);
    }

    //xとyが同じグループかどうかの判定をします
    bool same(int x,int y){
        return find(x)==find(y);
    }

    //xとyを同じグループにします
    //既に同じなら何もしません
    //weight(y)-weight(x)==wとなるように構成します
    void Unite(int x,int y,T w){
        w+=get_weight(x);
        w-=get_weight(y);
        x=find(x);
        y=find(y);
        if(x==y)return;
        if(Rank[x]>Rank[y]){
            parent[y]=x;
            weight[y]=w;
            cont[x]+=cont[y];
            cont[y]=0;
        }else{
            parent[x]=y;
            if(Rank[x]==Rank[y])Rank[y]++;
            weight[x]=-w;
            cont[y]+=cont[x];
            cont[x]=0;
        }
    }

    //xが属するグループの要素数を返します
    int group_size(int x){
        return cont[find(x)];
    }

    //デバッグ用
    void visual(){
        for(int i=0;i<size;i++)find(i);
        for(int i=0;i<size;i++){
            cout<<"   par["<<i<<"]="<<parent[i]<<",";
        }
        cout<<endl;
        for(int i=0;i<size;i++){
            cout<<"weight["<<i<<"]="<<weight[i]<<",";
        }
        cout<<endl;
        for(int i=0;i<size;i++){
            cout<<"cont["<<i<<"]="<<cont[i]<<",";
        }
        cout<<endl;
    }
private:
    int size;
    const T unity=0;//型Tの単位元
    vector<int> parent;//親
    vector<int> Rank;
    vector<int> cont;//グループに属する要素の個数
    vector<T> weight;//ポテンシャル
};


int main(){
	int n,m;
	while(cin>>n>>m,n){
		Potential_UF<ll> uf(n);
		for(int i=0;i<m;i++){
			char a;cin>>a;
			if(a=='!'){
				int b,c;
				ll d;
				cin>>b>>c>>d;
				b--;c--;
				uf.Unite(b,c,d);
			}else{
				int b,c;cin>>b>>c;
				b--;c--;
				if(!uf.same(b,c)){
					cout<<"UNKNOWN"<<endl;
				}else{
					cout<<uf.diff(b,c)<<endl;
				}
			}
		}
	}
}
