#include <iostream>
#include <fstream>
using namespace std;
ifstream fin ("disjoint.in");
ofstream fout ("disjoint.out");
int n,m;
int parent[100002];
int x,y,code;
//func that recieves random node and tries to find the root of the graph using the parent array
int find_root (int x) {
int root = x;
//within the parent array, if the parent of the curent number is 0 it means we have found the root, as it has no parent
while (parent[root] > 0) {
root = parent[root];
}
//the root variable will hold the value of the root node at the end of this loop
//for optimization we shall assign every node the parent value of the root
while (parent[x] > 0) {
parent[x] = root;
x = parent[x];
}
return root;
}
//func to join 2 graphs. we are going to assign one of the roots as the parent of the other
void join_graphs (int x, int y) {
parent[find_root(y)] = find_root(x);
}
//fucntion to check if two numbers belong to the same set or better said, if two nodes belong in the same graph
bool check_condition (int x, int y) {
if (find_root(x) == find_root(y))
return true;
else
return false;
}
int main () {
fin >> n >> m;
//because every set represent a graph with one node, it means that at the beginning every node is a root of it's own graph
for (int i=1; i<=n; i++) {
parent[i] = -1;
}
for (int i=1; i<=m; i++) {
fin >> code >> x >> y;
if (code == 1)
join_graphs (x,y);
else
if (check_condition(x,y))
fout << "DA\n";
else
fout << "NU\n";
}
return 0;
}