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

struct edge{
	edge(){}
	edge(ll from, ll to, ll cost, ll id) :from(from), to(to), cost(cost), id(id){}
	ll from, to, cost, id;
};

edge es[100000];
using Graph = vector<vector<edge>>;

int N, M;

const ll INF = 1LL << 55;

void dijkstra(int s, const Graph& g, vector<ll>& dist){
	using P = pair<ll, int>;
	dist = vector<ll>(N, INF);
	dist[s] = 0;
	priority_queue<P, vector<P>, greater<P>> q;
	q.push({ 0, s });
	while(q.size()){
		ll d = q.top().first, v = q.top().second;
		q.pop();
		for(auto e : g[v]){
			if(dist[e.to] > d + e.cost){
				dist[e.to] = d + e.cost;
				q.push({ d + e.cost, e.to });
			}
		}
	}
}

int use[100000];
int bri[100000];

using Pii = pair<int, int>;

std::pair<std::vector<int>, vector<Pii>> bridge(const Graph& g){
	const int n = g.size();
	int idx = 0, s = 0, t = 0, k = 0;
	std::vector<int> ord(n, -1), onS(n), stk(n), roots(n), cmp(n);
	vector<Pii> brdg;
	std::function<void(int, int)> dfs = [&](int v, int u){
		ord[v] = idx++;
		stk[s++] = v;
		onS[v] = true;
		roots[t++] = v;
		for(auto& e : g[v]){
			int w = e.to;
			if(ord[w] == -1)
				dfs(w, v);
			else if(u != w && onS[w])
				while(ord[roots[t - 1]] > ord[w]) --t;
		}
		if(v == roots[t - 1]){
			brdg.emplace_back(u, v);
			while(1){
				int w = stk[--s];
				onS[w] = false;
				cmp[w] = k;
				if(v == w) break;
			}
			--t;
			++k;
		}
	};
	for(int u = 0; u < n; u++){
		if(ord[u] == -1){
			dfs(u, n);
			brdg.pop_back();
		}
	}
	return std::make_pair(cmp, brdg);
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
#ifdef LOCAL
	std::ifstream in("in");
	std::cin.rdbuf(in.rdbuf());
#endif

	cin >> N >> M;

	Graph G(N), Gr(N);
	for(int i = 0; i < M; i++){
		ll u, v, cost;
		cin >> u >> v >> cost;
		u--, v--;
		es[i] = edge(u, v, cost, i);
		G[u].push_back(edge(u, v, cost, i));
		Gr[v].push_back(edge(v, u, cost, i));
	}

	vector<ll> d(N), dr(N);
	dijkstra(0, G, d);
	dijkstra(1, Gr, dr);

	ll dist = d[1];
	Graph G2(N);
	map<Pii, int> idmap;
	for(int i = 0; i < M; i++){
		edge e = es[i];
		ll dd = d[e.from] + e.cost + dr[e.to];
		if(dist == dd){
			use[i] = 1;
			for(int loop = 0; loop < 2; loop++){
				G2[e.from].push_back(e);
				idmap[{e.from, e.to}] = i;
				swap(e.from, e.to);
			}
		}
	}

	auto res = bridge(G2);
	for(auto p : res.second){
		for(int i = 0; i < 2; i++){
			if(idmap.count(p)){
				bri[idmap[p]] = 1;
			}
			swap(p.first, p.second);
		}
	}

	for(int i = 0; i < M; i++){
		if(!use[i]){
			edge e = es[i];
			ll dd = d[e.to] + e.cost + dr[e.from];
			if(dist > dd){
				cout << "HAPPY" << endl;
			}
			else{
				cout << "SOSO" << endl;
			}
		}
		else{
			if(bri[i]){
				cout << "SAD" << endl;
			}
			else{
				cout << "SOSO" << endl;
			}
		}
	}
}