#include <iostream>
#include <vector>
#include <fstream>
#include <queue>
using namespace std;
ifstream fin("disjoint.in");
ofstream fout("disjoint.out");
class graf {
int nrN;
int nrM;
vector<vector<int>> matriceAd;
public:
graf(int n, int m, vector<vector<int>> &mat) {
nrN = n;
nrM = m;
matriceAd = mat;
}
void citire_neorientat() {
for (int i = 0; i < nrM; ++i) {
int x, y;
fin >> x >> y;
matriceAd[x].push_back(y);
matriceAd[y].push_back(x);
}
}
void citire_orientat() {
for (int i = 0; i < nrM; ++i) {
int x, y;
fin >> x >> y;
matriceAd[x].push_back(y);
}
}
void citire_sortaret(vector<int> &dep){
for (int i = 0; i < nrM; ++i) {
int x, y;
fin>>x>>y;
matriceAd[x].push_back(y);
dep[y]++;
}
}
void BFS(int S) {
queue<int> coada;
int x, y;
vector<int> cost(nrN + 1, -1);
cost[S] = 0;
coada.push(S);
while (!coada.empty()) {
x = coada.front();
coada.pop();
for (int i = 0; i < matriceAd[x].size(); ++i) {
if (cost[matriceAd[x][i]] == -1) {
cost[matriceAd[x][i]] = cost[x] + 1;
coada.push(matriceAd[x][i]);
}
}
}
for (int i = 1; i < nrN + 1; i++)
fout << cost[i] << " ";
}
void DFS() {
queue<int> coada;
vector<int> viz(nrN + 1, 0);
int conex = 0;
for (int i = 1; i <= nrN; ++i) {
if (viz[i] == 0) {
conex++;
coada.push(i);
while (!coada.empty()) {
int x = coada.front();
viz[x]++;
coada.pop();
for (int j = 1; j < matriceAd[x].size(); ++j) {
if (viz[matriceAd[x][j]] == 0)
coada.push(matriceAd[x][j]);
}
}
}
}
fout << conex;
}
void sortaret(vector<int> &dep){
queue<int> coada;
vector<int> sortare;
for (int i = 1; i < nrN + 1; ++i) {
if (dep[i] == 0)
coada.push(i);
}
while (!coada.empty()){
int x = coada.front();
sortare.push_back(x);
coada.pop();
for (int i = 1; i < matriceAd[x].size(); ++i) {
dep[matriceAd[x][i]]--;
if (dep[matriceAd[x][i]] == 0)
coada.push(matriceAd[x][i]);
}
}
for (int i = 0; i < nrN; ++i) {
fout<<sortare[i]<<" ";
}
}
int reprez(int& x, vector<int> tata){
while(tata[x] != 0)
x = tata[x];
return x;
}
void op1(vector<int>& tata, vector<int>& h, int x, int y){
int a = reprez(x, tata), b = reprez(y, tata);
if (h[a] == h[b]){
tata[a] = b;
h[b]++;
}
else if (h[b] > h[a]) {
int aux;
while (tata[x] != 0) {
aux = tata[x];
tata[x] = b;
x = aux;
}
}
else{
int aux;
while (tata[y] != 0) {
aux = tata[y];
tata[y] = a;
x = aux;
}
}
}
void op2(int x, int y, vector<int> tata){
if (reprez(x, tata) == reprez(y, tata))
fout<<"DA"<<endl;
else
fout<<"NU"<<endl;
}
void solveDisjoint(){
vector<int> tata(nrN + 1, 0), h(nrN + 1, 0);
int op, x, y;
for (int i = 0; i < nrM; ++i) {
fin>>op>>x>>y;
if (op == 1)
op1(tata, h, x, y);
else
op2(x, y, tata);
}
}
};
///BFS
//int main(){
// int n, m, S;
// fin >> n >> m >> S;
// vector<vector<int>> mat;
// vector<int> aux(1,-1);
// mat.resize(n+1, aux);
// graf G(n, m, mat);
// G.citire_orientat();
// G.BFS(S);
//
// return 0;
//}
///DFS
//int main(){
// int n, m;
// fin>>n>>m;
// vector<vector<int>> mat;
// vector<int> aux(1,-1);
// mat.resize(n+1, aux);
// graf G(n, m, mat);
// G.citire_neorientat();
// G.DFS();
// return 0;
//}
///sortaret
//int main(){
// int n, m;
// fin>>n>>m;
// vector<int> dep(n + 1, 0);
// vector<vector<int>> mat;
// vector<int> aux(1,-1);
// mat.resize(n+1, aux);
// graf G(n, m, mat);
// G.citire_sortaret(dep);
// G.sortaret(dep);
// return 0;
//}
///disjoint
int main(){
int n, m;
fin>>n>>m;
vector<vector<int>> mat;
graf G(n , m, mat);
G.solveDisjoint();
return 0;
}