#include <bits/stdc++.h>
using namespace std;
#define FOR(i,k,n) for(int i = (int)(k); i < (int)(n); i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(a) a.begin(), a.end()
#define MS(m,v) memset(m,v,sizeof(m))
#define D10 fixed<<setprecision(10)
typedef long long ll;
typedef long double ld;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef pair <int, ll> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template<class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/

struct UnionFind
{
	vector<int> par;
	UnionFind(int n) :par(n, -1) {}
	int find(int x) { return par[x] < 0 ? x : par[x] = find(par[x]); }
	void unite(int x, int y)
	{
		x = find(x); y = find(y);
		if (x == y) return;
		if (par[y] < par[x]) swap(x, y);
		if (par[x] == par[y]) par[x]--;
		par[y] = x;
		if (find(x) != find(y)) par[find(y)] = x;
	}
	int count()
	{
		int cnt = 0;
		REP(i, par.size()) if (par[i] < 0) cnt++;
		return cnt;
	}
	bool same(int x, int y)
	{
		return find(x) == find(y);
	}
};

typedef tuple<char, vi> query;

vector<query> q;
vector<vector<pii>> es;

int main()
{
	cin.sync_with_stdio(false);
	int n, m;
	while (cin >> n >> m, n)
	{
		UnionFind uf1(n);
		q.clear();
		es.clear(); es.resize(n);
		REP(i, m)
		{
			char c;
			cin >> c;
			int p = (c == '!' ? 3 : 2);
			vi v(p);
			REP(i, p) cin >> v[i];
			v[0]--; v[1]--;
			q.emplace_back(c, v);
			if (c == '!')
			{
				uf1.unite(v[0], v[1]);
				es[v[0]].emplace_back(v[1], v[2]);
				es[v[1]].emplace_back(v[0], -v[2]);
			}
		}
		vi dist(n, INF);
		REP(i, n)
		{
			if (uf1.par[i] >= 0) continue;
			dist[i] = 0;
			queue<int> que;
			que.push(i);
			while (que.size())
			{
				int t = que.front();
				que.pop();
				for (auto j: es[t])
				{
					if (dist[j.first] != INF) continue;
					dist[j.first] = dist[t] + j.second;
					que.push(j.first);
				}
			}
		}
		UnionFind uf2(n);
		for (auto i: q)
		{
			vi v = get<1>(i);
			if (get<0>(i) == '!') uf2.unite(v[0], v[1]);
			else
			{
				if (uf2.same(v[0], v[1]))
				{
					cout << dist[v[1]] - dist[v[0]] << endl;
				}
				else
				{
					cout << "UNKNOWN" << endl;
				}
			}
		}
	}
	return 0;
}