#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <map>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <set>
#include <stack>
#include <queue>
#include <utility>
#include <cassert>
#include <bitset>
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define fi first
#define se second
#define pb push_back
#define mkp make_pair
#define rep(i,a,b) for (int i=(a);i<(b);i++)
#define per(i,a,b) for (int i=(b)-1;i>=(a);i--)
#define REP(i,a,b) for (int i=(a);i<=(b);i++)
#define PER(i,a,b) for (int i=(b);i>=(a);i--)
#define de(x) cout<<">> "<<#x<<" = "<<x<<endl;
using namespace std;
typedef long long LL;
typedef pair<LL, int> P;
LL powmod(LL a,LL b,LL mod) {LL res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
LL gcd(LL a, LL b) {if (b==0)return a;else return gcd(b,a%b);}
const int INF = 0x3f3f3f3f;
const int MAXN = 1000005; // 1e6;
int u[MAXN],v[MAXN],c[MAXN];
int mark[MAXN];
int bridge[MAXN];
vector<P> G[MAXN];
vector<P> RG[MAXN];
vector<P> NG[MAXN];
LL d[MAXN],rd[MAXN];
int ans[MAXN];
int n,m;
void dij(vector<P> GG[], LL dis[], int s)
{
	dis[s]=0;
	priority_queue<P, vector<P>, greater<P> > que;
	que.push(mkp(0, s));
	while(!que.empty()){
		int x=que.top().se;
		LL d=que.top().fi;
		que.pop();
		if (d>dis[x]) continue;
		rep(i,0,SZ(GG[x]))
		{
			int v=GG[x][i].fi, e = GG[x][i].se;
			if (dis[v]>dis[x]+e){
				dis[v]=dis[x]+e;
				que.push(mkp(dis[v],v));
			}
		}
	}
}
int dfn[MAXN],low[MAXN],idx;
void Tarjan(int i, int fa)
{
        low[i]=dfn[i]=idx++;
        rep(j,0,NG[i].size())
        {
                int v = NG[i][j].fi;
                if (v==fa) continue;
                if (!dfn[v])
                {
                        Tarjan(v,i);
                        low[i] = min(low[i],low[v]);
                        if (low[v] > dfn[i]) bridge[NG[i][j].se]=true;
                }
                else if (dfn[v] < dfn[i])
                {
                        low[i]=min(low[i],dfn[v]);
                }
        }
}
int main()
{
	// freopen("in.txt","r",stdin);
	scanf("%d%d",&n,&m);
	// de(m)
	rep(i, 1, m+1){
		scanf("%d%d%d",u+i,v+i,c+i);
		G[u[i]].pb(mkp(v[i],c[i]));
		RG[v[i]].pb(mkp(u[i],c[i]));
	}
	// de(m)
	memset(d,INF,sizeof d);
	memset(rd,INF,sizeof rd);
	dij(G,d,1);
	dij(RG,rd,2);
	// de(m)
	rep(i, 1, m+1){
		if (d[u[i]] + rd[v[i]] + c[i] == d[2]) 
		{
			mark[i]=true;
			NG[u[i]].pb(mkp(v[i], i));
			NG[v[i]].pb(mkp(u[i], i));
		}
	}
	// de(m)
	Tarjan(1,-1);
	// de(m)
	rep(i, 1, m+1)
	{
		// de(1)
		if (mark[i] && bridge[i]) puts("SAD");
		else if (mark[i] && !bridge[i]) puts("SOSO");
		else if (!mark[i] && d[v[i]] + rd[u[i]] + c[i] < d[2]) puts("HAPPY");
		else if (!mark[i] && d[v[i]] + rd[u[i]] + c[i] >= d[2]) puts("SOSO");
	}
	return 0;
}


