#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define sd(x) scanf("%d", &(x))
#define pii pair<int, int>
#define F first
#define S second

#ifdef LOCAL
#define cerr cout
#else
#endif

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
	cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
	const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif

const int N = 1005;
const int M = 200005;
bool not_necessary[N][N];
vector<int> con[N];
int a[M], b[M];
int vis[N];
int fe[N];

struct graph {
  int n;
  vector<vector<int>> adj;
  graph(int n) : n(n), adj(n) { }
  void add_edge(int src, int dst) {
    adj[src].push_back(dst);
  }

  vector<vector<int>> strongly_connected_components() {
    vector<vector<int>> scc;
    vector<int> S, B, I(n);
    function<void(int)> dfs = [&](int u) {
      B.push_back(I[u] = S.size());
      S.push_back(u);
      for (int v: adj[u]) {
        if (!I[v]) dfs(v);
        else while (I[v] < B.back()) B.pop_back();
      }
      if (I[u] == B.back()) {
        scc.push_back({});
        B.pop_back();
        for (; I[u] < S.size(); S.pop_back()) {
          scc.back().push_back(S.back());
          I[S.back()] = n + scc.size();
        }
      }
    };
    for (int u = 0; u < n; ++u)
      if (!I[u]) dfs(u);
    return scc; // I[u] - n is the index of u
  }
};

template<class T>
struct fixedSizeQueue{
	int n, L, R;
	T * arr;
	fixedSizeQueue(int n) : n(n){
		arr = new T[2 * n + 10];
		L = n + 5;
		R = L - 1;
	}

	void push_back(T x){
		arr[++R] = x; 
	}

	void push_front(T x){
		arr[--L] = x;
	}
	
	T front(){
		return arr[L];
	}

	T back(){
		return arr[R];
	}

	T pop_front(){
		if(L > R){
			throw runtime_error("empty queue access");
			return T();
		}
		return arr[L++];
	}

	T pop_back(){
		if(L > R){
			throw runtime_error("empty queue access");
			return T();
		}
		return arr[R--];
	}

	void re_init_indices(){
		L = n + 5;
		R = L - 1;
	}

	bool empty(){
		return L > R;
	}
};
int main(){
	int n, m; sd(n); sd(m);
	graph g(n + 1);
	for(int i = 1; i <= m; i++){
		sd(a[i]);
		sd(b[i]);
		con[a[i]].push_back(b[i]);
		g.add_edge(a[i], b[i]);
	}
	vector<vector<int>> comp = g.strongly_connected_components();
	vector<int> where(n + 1);
	for(int i = 0; i < comp.size(); i++)
		for(auto it : comp[i])
			where[it] = i;
	fixedSizeQueue<pii> q(2 * n);
	for(int i = 1; i <= n; i++){
		q.re_init_indices();
		memset(vis, 0, sizeof vis);
		for(int v : con[i]){
			q.push_back({v, v});
			vis[v] = 1;
			fe[v] = v;
		}
		while(!q.empty()){
			auto it = q.pop_back();
			int u = it.F, firstEdge = it.S;
			for(int v : con[u]){
				if(v == i || vis[v] >= 2) continue;
				if(vis[v] == 1 && firstEdge == fe[v]) continue;
				q.push_back({v, firstEdge});
				if(vis[v] == 0)
					fe[v] = firstEdge;
				vis[v]++;
			}
		}
		for(int v : con[i]) if(vis[v] == 2){
			not_necessary[i][v] = 1;
		}
	}
	for(int i = 1; i <= m; i++){

		printf( (not_necessary[a[i]][b[i]] ^ (where[a[i]] != where[b[i]] )) ? "same\n" : "diff\n");
	}
}

Measured memory_bytes: 7552