// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef pair<ll,ll> P;

ll V,E;

struct edge{

	ll to,cost,id;

};

const ll maxn = 100005;

const ll INF = 102120027425345LL;

vector<edge> G[maxn],rG[maxn],sG[maxn];

ll d[maxn], d2[maxn];

bool isBridge[maxn];

void dijkstra(ll s, vector<edge> G[maxn], ll d[maxn]) {

	priority_queue<P, vector<P>, greater<P> > que;

	fill(d, d+V, INF);

	d[s] = 0;

	que.push(P(0,s));

	while (!que.empty()) {

		P p = que.top(); que.pop();

		ll v = p.second;

		if (d[v] < p.first) continue;

		for (auto e:G[v]){

			if (d[e.to] > d[v] + e.cost) {

				d[e.to] = d[v] + e.cost;

				que.push(P(d[e.to],e.to));

			}			

		}

	}

}

	map<P,ll> M;

ll dfs_clock,pre[maxn],low[maxn];

ll dfs(ll u, ll fa) {

	ll lowu = pre[u] = ++dfs_clock;

	for (auto e: sG[u]) {

		ll v = e.to;

		if (!pre[v]) {

			ll lowv = dfs(v,u);

			lowu = min(lowu, lowv);

			if (lowv > pre[u]){

				if (M[P(u,v)]==1) isBridge[e.id] = true;

			}

		}

		else if (pre[v] <pre[u]&&fa!=v) lowu = min(lowu, pre[v]);

	}

	return low[u] = lowu;

}



ll ans[maxn];





int main() {

	scanf("%d%d", &V, &E);



	for (ll i = 0; i < E; i++) {

		ll x,y,cost;

		scanf("%lld%lld%lld",&x,&y,&cost);

		--x,--y;

		

		G[x].push_back(edge{y,cost,i});

		rG[y].push_back(edge{x,cost,i});	

	}

	dijkstra(0,G,d);

	dijkstra(1,rG,d2);

	for(ll i = 0; i < V; i++)

	for (auto e:G[i]) {

		//cerr << i << " "  <<e.to <<" " << d[i] << " " << e.cost << " " << d[e.to] << endl;

		if (d[i] + e.cost == d[e.to]&&d[e.to]+d2[e.to]==d[1]) 

		{

			sG[i].push_back(e),sG[e.to].push_back(edge{i,e.cost,e.id});//cerr << i << " "  <<e.to<<endl; 

			M[P(i,e.to)]++;

		}

	}

	//cerr << "------" << endl;

	dfs(0,-1);

	//for (ll i = 0; i < E; i++) cerr<< isBridge[i] << " " ;

	//cerr<<endl;

	for(ll i = 0; i < V; i++)

	for (auto e:G[i]) {

		if (isBridge[e.id]) ans[e.id] = -1;

		else {

			if (d[e.to] + e.cost + d2[i] < d[1]) ans[e.id] = 1;

			else ans[e.id] = 0;

		}

	}

	for (ll i = 0; i < E; i++) {

		if (ans[i] == -1) puts("SAD");

		else if (ans[i] == 0) puts("SOSO");

		else puts("HAPPY");

	}

	

	



}




// Faster C++ solution for the same problem (measured speedup: 1.4403759873910928x):
#include <bits/stdc++.h>



using namespace std;



const int maxn = 100000;

const int maxm = 100000;



class Node

{

public:

	int u;

	long long d;



	Node(void);

	Node(const int &, const long long &);



	bool operator < (const Node &) const;

};



class Edge

{

public:

	int u;

	int v;

	int w;



	Edge(void);

	Edge(const int &, const int &, const int &);

};



Node::Node(void) : u(0), d(0)

{



}



Node::Node(const int & u, const long long & d) : u(u), d(d)

{



}



bool Node::operator < (const Node & rhs) const

{

	return d > rhs.d;

}



Edge::Edge(void) : u(0), v(0), w(0)

{



}



Edge::Edge(const int & u, const int & v, const int & w) : u(u), v(v), w(w)

{



}



int n, m;

vector<Edge> E;

vector<int> Eid[maxn];

vector<Edge> Et;

vector<int> Etid[maxn];

long long d[maxn];

long long deg[maxn];

long long dt[maxn];

long long degt[maxn];



void dijkstra(const int & s, vector<Edge> & E, vector<int> Eid[], long long d[], long long deg[])

{

	Node cur, tgt;

	priority_queue<Node> que;



	memset(d, 0x3f, sizeof(d[0]) * n);

	memset(deg, 0, sizeof(deg[0]) * n);

	d[s] = 0;

	deg[s] = 1;

	for (que.push(Node(s, 0)); !que.empty(); )

	{

		cur = que.top();

		que.pop();



		if (d[cur.u] < cur.d)

			continue;



		int u = cur.u, v, w;

		for (int i = 0; i < Eid[u].size(); ++ i)

		{

			v = E[Eid[u][i]].v;

			w = E[Eid[u][i]].w;

			if (d[v] > d[u] + w)

			{

				d[v] = d[u] + w;

				deg[v] = deg[u];

				que.push(Node(v, d[v]));

			}

			else if (d[v] == d[u] + w)

				deg[v] += deg[u];

		}

	}

}



inline int check_edge(const int & idx)

{

	if (d[E[idx].v] + E[idx].w + dt[E[idx].u] < d[1])

		return -1;

	else if (d[E[idx].u] + E[idx].w + dt[E[idx].v] == d[1] && deg[E[idx].u] * degt[E[idx].v] == deg[1])

		return 1;

	else

		return 0;

}



int main()

{

	ios_base::sync_with_stdio(false);



	cin >> n >> m;

	for (int i = 0; i < m; ++ i)

	{

		int u, v, w;



		cin >> u >> v >> w;

		-- u;

		-- v;

		E.push_back(Edge(u, v, w));

		Eid[u].push_back(i);

		Et.push_back(Edge(v, u, w));

		Etid[v].push_back(i);

	}



	dijkstra(0, E, Eid, d, deg);

	dijkstra(1, Et, Etid, dt, degt);



	int ans;

	for (int k = 0; k < m; ++ k)

	{

		ans = check_edge(k);



		if (ans == -1)

			cout << "HAPPY";

		else if (ans == 0)

			cout << "SOSO";

		else

			cout << "SAD";

		cout << endl;

	}



	return 0;

}