#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;

class BECC{
private:
    int N;
    vector<vector<int>> G,dcmp;
    vector<int> order,inS;
    stack<int> S,roots;
    vector<int> cmp;
public:
    vector<P> bridge;
    vector<vector<int>> bccs;
    BECC(int n,vector<vector<int>> graph){
        N = n;
        G = graph;
        order = inS = cmp = vector<int>(N+1,0);
    }
    void dfs(int cur,int prev,int k){
        order[cur] = ++k; //訪問順に番号付け
        S.push(cur); inS[cur] = true;//訪問した頂点の集合に追加
        roots.push(cur);//各bccの根を管理
        for(auto to:G[cur]){
            if(order[to]==0) dfs(to,cur,k);
            else if(to!=prev && inS[to]){//後退辺なら
                while(order[roots.top()]>order[to]) roots.pop();//(to,cur]を捨てる
            }
        }
        if(cur==roots.top()){
            if(prev!=-1) bridge.emplace_back(prev,cur);//根でないなら橋になる
            vector<int> bcc;
            while(true){
                int node = S.top(); S.pop(); inS[node] = false;//nodeを捨てる
                bcc.emplace_back(node);//nodeをbccに追加
                cmp[node] = bccs.size()+1;
                if(node==cur) break;
            }
            bccs.emplace_back(bcc);
            roots.pop();
        }
    }
    void bridge_detection(){
        int k = 0;
        for(int i=0;i<N;i++) if(order[i]==0) dfs(i,-1,k);
    }
    int find(int n){return cmp[n];}
    int cmp_size(int n){return bccs[cmp[n]].size();}
    void decomposition(){
        int k = 0;
        for(int i=0;i<N;i++) if(order[i]==0) dfs(i,-1,k);
        dcmp = vector<vector<int>>(bccs.size()+1);
        for(auto x:bridge){
            dcmp[cmp[x.first]].push_back(cmp[x.second]);
            dcmp[cmp[x.second]].push_back(cmp[x.first]);
        }
    }
};

int main(){
    int N,M;
    cin >> N >> M;
    vector<ll> A(M),B(M),C(M);
    vector<vector<P>> g(N),rg(N);
    for(int i=0;i<M;i++){
        cin >> A[i] >> B[i] >> C[i];
        A[i]--,B[i]--;
        g[A[i]].push_back({C[i],B[i]});
        rg[B[i]].push_back({C[i],A[i]});
    }
    ll inf = 1e18;
    vector<vector<ll>> dp(N,vector<ll>(2,inf));
    auto dijkstra = [&](vector<vector<P>> v,int id){
        dp[id][id] = 0;
        priority_queue<P,vector<P>,greater<P>> Q;
        Q.push({0,id});
        while(!Q.empty()){
            P now = Q.top(); Q.pop();
            if(dp[now.second][id]<now.first) continue;
            for(auto& e:v[now.second]){
                ll nd = now.first+e.first;
                if(dp[e.second][id]>nd){
                    dp[e.second][id] = nd;
                    Q.push({nd,e.second});
                }
            }
        }
    };
    dijkstra(g,0);
    dijkstra(rg,1);
    vector<vector<int>> edges(N);
    for(int i=0;i<M;i++){
        if(dp[A[i]][0]+C[i]+dp[B[i]][1]==dp[1][0]){
            edges[A[i]].push_back(B[i]);
            edges[B[i]].push_back(A[i]);
        }
    }
    BECC becc(N,edges);
    becc.bridge_detection();
    set<P> bridge;
    for(auto& x:becc.bridge){
        int a = min(x.first,x.second),b = max(x.first,x.second);
        bridge.insert({a,b});
    }
    for(int i=0;i<M;i++){
        int a = min(A[i],B[i]),b = max(A[i],B[i]);
        ll nd = dp[B[i]][0]+C[i]+dp[A[i]][1];
        if(nd<dp[1][0]) cout << "HAPPY" << endl;
        else if(nd==dp[1][0]) cout << "SOSO" << endl;
        else if(dp[A[i]][0]+C[i]+dp[B[i]][1]==dp[0][1] && bridge.count({a,b})) cout << "SAD" << endl;
        else cout << "SOSO" << endl;
    }
}


Measured memory_bytes: 54900