#include <bits/stdc++.h>
#define int long long
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
typedef pair<int,int>P;
typedef pair<int,P>P2;
#define fi first
#define se second

struct Bridge{
  int n;
  vector<vector<int> > G;
  vector<int>low,used,depth;
  set<pair<int,int> >ans;
  Bridge(){}
  Bridge(int sz):n(sz),low(sz),used(sz),depth(sz),G(sz){}
  void add(int a,int b){
    G[a].push_back(b);
    G[b].push_back(a);
  }
  void dfs(int x,int d,int prev){
    depth[x]=d;
    for(int i=0;i<G[x].size();i++){
      int nx=G[x][i];
      if(nx==prev)continue;
      if(!used[nx]){
        used[nx]=true;
        dfs(nx,d+1,x);
        if(!low[nx]) ans.insert(P(min(x,nx),max(x,nx)));
        low[x]+=low[nx];
      }
      else if(d>depth[nx])low[nx]--,low[x]++;
    }
  }
  void build(){if(!n)return ;
    fill(used.begin(),used.end(),0);
    fill(low.begin(),low.end(),0);
    fill(depth.begin(),depth.end(),0);
    used[0]=1;
    dfs(0,0,0);
  }
  void prin(){
    set<P>::iterator it=ans.begin();
    while(it!=ans.end()){
      cout<< (*it).first <<' '<< (*it).second <<endl;
      it++;
    }
  }
};

vector<P>v[100009],v2[100009];
int d1[100009],d2[100009],s,t,n,m;
int a[100009],b[100009],c[100009];
map<P,int>MIN,TT;

set<P2> iru;

void dij1(){
    r(i,100009)d1[i]=1e14;
    d1[s]=0;
    priority_queue<P,vector<P>,greater<P> >q;
    q.push(P(0,s));
    while(!q.empty()){
        P p=q.top();q.pop();
        int now=p.se;
        int cost=p.fi;
        if(d1[now]<cost)continue;
        r(i,v[now].size()){
            int nex=v[now][i].fi;
            int cost2=cost+v[now][i].se;
            if(d1[nex]<=cost2)continue;
            d1[nex]=cost2;
            q.push(P(cost2,nex));
        }
    }
}

void dij2(){
    r(i,100009)d2[i]=1e14;
    d2[t]=0;
    priority_queue<P,vector<P>,greater<P> >q;
    q.push(P(0,t));
    while(!q.empty()){
        P p=q.top();q.pop();
        int now=p.se;
        int cost=p.fi;
        if(d2[now]<cost)continue;
        r(i,v2[now].size()){
            int nex=v2[now][i].fi;
            int cost2=cost+v2[now][i].se;
            if(d2[nex]<=cost2)continue;
            d2[nex]=cost2;
            q.push(P(cost2,nex));
        }
    }
}

int cnt=0;
set<int>st;
set<P>PPP;

void iranai(){
    r(i,m){//cout<<d1[a[i]]<<' '<<d2[b[i]]<<" "<<c[i]<<endl;
        if(d1[a[i]]+d2[b[i]]+c[i]==d1[t]){
            iru.insert(P2(a[i],P(b[i],c[i])));
            cnt++;
            st.insert(a[i]);
            st.insert(b[i]);
        }
    }
}

signed main(){
    cin>>n>>m;
    r(i,m){
        cin>>a[i]>>b[i]>>c[i];
        a[i]--;
        b[i]--;
        v[a[i]].push_back(P(b[i],c[i]));
        v2[b[i]].push_back(P(a[i],c[i]));
        if(MIN.count(P(a[i],b[i]))){
            if(MIN[P(a[i],b[i])]==c[i])TT[P(a[i],b[i])]=1;
            MIN[P(a[i],b[i])]=min(MIN[P(a[i],b[i])],c[i]);
        }
        else MIN[P(a[i],b[i])]=c[i];
    }
    s=0;
    t=1;
    dij1();
    dij2();
    iranai();
    set<P2>::iterator it=iru.begin();
    int N=st.size();
    Bridge B(N);
    set<int>::iterator it2=st.begin();
    map<int,int>m1,m2;
    set<int>sss;
    int cc=0;
    for(;it2!=st.end();it2++){
        int A=(*it2);
        if(!sss.count(A)){
            sss.insert(A);//cout<<A<<endl;
            m1[A]=cc;
            m2[cc]=A;
            cc++;
        }
    }
    for(;it!=iru.end();it++){
        P2 p=(*it);
        int A=p.fi;
        int BB=p.se.fi;//cout<<m1[A]<<' '<<m1[BB]<<endl;
        PPP.insert(P(A,BB));
        B.add(m1[A],m1[BB]);
    }
    B.build();//cout<<d1[t]<<endl;
    r(i,m){
        int g=d1[b[i]]+d2[a[i]]+c[i];
        if(g<d1[t])cout<<"HAPPY"<<endl;
        else if(g==d1[t])cout<<"SOSO"<<endl;
        else{
            if((MIN[P(a[i],b[i])]==c[i])&&
                !TT.count(P(a[i],b[i]))&&
                m1.count(a[i])&&
                m1.count(b[i])&&
                PPP.count(P(a[i],b[i]))&&
                B.ans.count(P(min(m1[a[i]],m1[b[i]]),max(m1[a[i]],m1[b[i]]))))cout<<"SAD"<<endl;
            else cout<<"SOSO"<<endl;
        }
    }
}
