/**
 *    author:  tourist
 *    created: 20.01.2020 17:37:20       
**/
#include <bits/stdc++.h>

using namespace std;

template <typename T>
class graph {
 public:
  struct edge {
    int from;
    int to;
    T cost;
  };

  vector<edge> edges;
  vector<vector<int>> g;
  int n;

  graph(int _n) : n(_n) {
    g.resize(n);
  }

  virtual int add(int from, int to, T cost) = 0;
};

template <typename T>
class digraph : public graph<T> {
 public:
  using graph<T>::edges;
  using graph<T>::g;
  using graph<T>::n;

  digraph(int _n) : graph<T>(_n) {
  }

  int add(int from, int to, T cost = 1) {
    assert(0 <= from && from < n && 0 <= to && to < n);
    int id = (int) edges.size();
    g[from].push_back(id);
    edges.push_back({from, to, cost});
    return id;
  }

  digraph<T> reverse() const {
    digraph<T> rev(n);
    for (auto &e : edges) {
      rev.add(e.to, e.from, e.cost);
    }
    return rev;
  }
};

template <typename T>
vector<int> find_scc(const digraph<T> &g, int &cnt) {
  digraph<T> g_rev = g.reverse();
  vector<int> order;
  vector<bool> was(g.n, false);
  function<void(int)> dfs1 = [&](int v) {
    was[v] = true;
    for (int id : g.g[v]) {
      auto &e = g.edges[id];
      int to = e.to;
      if (!was[to]) {
        dfs1(to);
      }
    }
    order.push_back(v);
  };
  for (int i = 0; i < g.n; i++) {
    if (!was[i]) {
      dfs1(i);
    }
  }
  vector<int> c(g.n, -1);
  function<void(int)> dfs2 = [&](int v) {
    for (int id : g_rev.g[v]) {
      auto &e = g_rev.edges[id];
      int to = e.to;
      if (c[to] == -1) {
        c[to] = c[v];
        dfs2(to);
      }
    }
  };
  cnt = 0;
  for (int id = g.n - 1; id >= 0; id--) {
    int i = order[id];
    if (c[i] != -1) {
      continue;
    }
    c[i] = cnt++;
    dfs2(i);
  }
  return c;
  // c[i] <= c[j] for every edge i -> j
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  vector<int> from(m), to(m);
  digraph<int> g(n);
  vector<vector<int>> gr(n);
  for (int i = 0; i < m; i++) {
    cin >> from[i] >> to[i];
    --from[i]; --to[i];
    g.add(from[i], to[i]);
    gr[from[i]].push_back(to[i]);
  }
  int cnt;
  vector<int> comp = find_scc(g, cnt);
  vector<vector<int>> gc(cnt);
  for (int i = 0; i < m; i++) {
    if (comp[from[i]] != comp[to[i]]) {
      gc[comp[from[i]]].push_back(comp[to[i]]);
    }
  }
  vector<vector<int>> reach(cnt, vector<int>(cnt, 0));
  for (int i = 0; i < cnt; i++) {
    reach[i][i] = 1;
    for (int j = i; j < cnt; j++) {
      if (reach[i][j]) {
        for (int k : gc[j]) {
          reach[i][k] = min(2, reach[i][k] + reach[i][j]);
        }
      }
    }
  }
  vector<vector<int>> root(n, vector<int>(n, -1));
  for (int start = 0; start < n; start++) {
    vector<int> que;
    for (int j : gr[start]) {
      que.emplace_back(j);
      root[start][j] = j;
    }
    for (int b = 0; b < (int) que.size(); b++) {
      for (int j : gr[que[b]]) {
        if (j == start) {
          continue;
        }
        if (root[start][j] == -1 || (root[start][j] >= 0 && root[start][j] != root[start][que[b]])) {
          que.push_back(j);
          if (root[start][j] == -1) {
            root[start][j] = root[start][que[b]];
          } else {
            root[start][j] = -2;
          }
        }
      }
    }
  }
  for (int i = 0; i < m; i++) {
    if (comp[from[i]] != comp[to[i]]) {
      cout << (reach[comp[from[i]]][comp[to[i]]] == 1 ? "same" : "diff") << '\n';
    } else {
      cout << (root[from[i]][to[i]] == to[i] ? "diff" : "same") << '\n';
    }
  }
  return 0;
}


Measured memory_bytes: 17288