#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
typedef ll Weight;
struct Edge{
  int src, dst;
  Weight weight;
  Edge(int src, int dst, Weight weight) : src(src), dst(dst), weight(weight) {}
};

const ll INF = 1e15;

bool operator < (const Edge &e, const Edge &f){
  return e.weight != f.weight ? e.weight > f.weight :
    e.src != f.src ? e.src < f.src : e.dst < f.dst;
}

typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
void shortestPath(const Graph &g, int s, vector<Weight> &dist, vector<vector<int> > &prev){
  int n = g.size();
  dist.assign(n, INF); dist[s] = 0;
  prev.assign(n, vector<int>());
  priority_queue<Edge> Q;
  for(Q.push(Edge(-2, s, 0)); !Q.empty();){
    Edge e = Q.top(); Q.pop();
    for(auto f=g[e.dst].begin();f!=g[e.dst].end();f++){
      if(dist[f->dst] > e.weight + f->weight){
	dist[f->dst] = e.weight + f->weight;
	Q.push(Edge(f->src, f->dst, e.weight + f->weight));
	prev[f->dst].clear();
	prev[f->dst].push_back(f->src);
      }else if(dist[f->dst] == e.weight + f->weight){
	prev[f->dst].push_back(f->src);
      }
    }
  }
}

pair<Graph, Graph> buildPath(const vector<vector<int> > &prev, int t){
  ll n = prev.size();
  Graph g(n);
  Graph g2(n);
  stack<int> st;
  st.push(t);
  vector<int> visited(n);
  while(!st.empty()){
    ll now = st.top();
    st.pop();
    if(visited[now])
      continue;
    visited[now] = true;
    for(auto&& p : prev[now]){
      if(p < 0)
	continue;
      g[p].push_back(Edge(p, now, 1));
      g2[p].push_back(Edge(p, now, 1));
      g[now].push_back(Edge(now, p, 1));
      st.push(p);
    }
  }
  return pair<Graph, Graph>(g, g2);
}

int main(){
  ll n, m;
  cin >> n >> m;
  n += 100;
  Graph g(n);
  Graph ginv(n);
  Edges es;
  map<P, P> mp;
  for(int i=0;i<m;i++){
    ll s, d, w;
    cin >> s >> d >> w;
    s--; d--;
    g[s].push_back(Edge(s, d, w));
    ginv[d].push_back(Edge(d, s, w));
    es.push_back(Edge(s, d, w));
    if(mp.find(P(s, d)) == mp.end())
      mp[P(s, d)] = P(w*2, 1);
    else{
      P befo = mp[P(s, d)];
      if(w*2 == befo.first)
	mp[P(s, d)] = P(w*2-1, befo.second + 1);
      else
	mp[P(s, d)] = P(min(w*2, befo.first), befo.second + 1);
    }
  }
  vector<Weight> sdist;
  vector<Weight> gdist;
  vector<vector<int> > prev;
  shortestPath(ginv, 1, gdist, prev);
  shortestPath(g, 0, sdist, prev);
  Graph tree, tree2;
  tie(tree, tree2) = buildPath(prev, 1);
  for(int i=0;i<tree2.size();i++){
    sort(tree2[i].begin(), tree2[i].end());
  }
  /*for(int i=0;i<n;i++){
    cout << i << ": " << sdist[i] << endl;
  }
  for(int i=0;i<n;i++){
    cout << i << ": " << gdist[i] << endl;
    }*/

  vector<int> order(n), low(n);
  vector<char> reach(n);
  int cnt=0;
  function<int(int, int)> dfs=[&](int v, int pv){
    if(reach[v]) return order[v];
    reach[v]=true;
    order[v]=cnt;
    int mlow=cnt;
    cnt++;
    for(auto&& e:tree[v]){
      if(e.dst==pv) continue;
      mlow = min(mlow, dfs(e.dst, v));
    }
    return low[v] = mlow;
  };
  dfs(0, -1);

  /*for(int i=0;i<n;i++)
    for(int j=0;j<tree[i].size();j++)
        cout << "tr: " << tree[i][j].src << " " << tree[i][j].dst << endl;
  */
  for(auto &&e : es){
    ll ans = 0;
    ll s, d, w;
    s = e.src; d = e.dst; w = e.weight;
    ll usedist = sdist[d] + w + gdist[s];
    //cout << sdist[d] << " " << w << " " << gdist[s] << endl;
    //cout << s << " " << d << " " << w << " " << usedist << " " << sdist[1] << endl;
    //for(auto &&e : )
    if(usedist < sdist[1])
      ans = max(ans, (ll)2);
    if(usedist == sdist[1])
      ans = max(ans, (ll)1);
    
    if(mp.find(P(s, d)) != mp.end() && mp[P(s, d)].first < w*2)
      ans = max(ans, (ll)1);
    bool ok = false;
    ok |= binary_search(tree2[s].begin(), tree2[s].end(), Edge(s, d, 1));
    if(!ok)
      ans = max(ans, (ll)1);
    if(order[e.src] >= low[e.dst] && order[e.dst] >= low[e.src] && ok)
      ans = max(ans, (ll)1);
    if(ans == 2)
      cout << "HAPPY" << endl;
    else if(ans == 1)
      cout << "SOSO" << endl;
    else
      cout << "SAD" << endl;
  }
  return 0;
}
/*
11 15
1 3 1
3 6 2
6 10 1
1 5 3
3 7 1
5 9 1
9 11 1
7 8 1
1 4 2
4 8 1
8 10 1
10 11 1
11 2 1
10 7 1
10 1 1
 */

Measured memory_bytes: 60272