#include <bits/stdc++.h>
#define DIM 100010
using namespace std;
class InParser {
private:
FILE *fin;
char *buff;
int sp;
char read_ch() {
++sp;
if (sp == 4096) {
sp = 0;
fread(buff, 1, 4096, fin);
}
return buff[sp];
}
public:
InParser(const char* nume) {
fin = fopen(nume, "r");
buff = new char[4096]();
sp = 4095;
}
InParser& operator >> (int &n) {
char c;
while (!isdigit(c = read_ch()) && c != '-');
int sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
InParser& operator >> (long long &n) {
char c;
n = 0;
while (!isdigit(c = read_ch()) && c != '-');
long long sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
};
struct segment_tree{
set<int> s1; /// valorile astea se afla in unele elemente din interval
set<int> s2; /// valorile astea se afla in toate elementele din interval
} aint[DIM*4];
vector <int> L[DIM];
int first[DIM],last[DIM],g[DIM];
int n,m,q,x,y,tip,ok,idx,i;
void dfs (int nod){
first[nod] = ++idx;
for (auto vecin : L[nod])
dfs (vecin);
last[nod] = idx;
}
void update (int nod, int st, int dr, int x, int y, int val){
aint[nod].s1.insert(val);
if (x <= st && dr <= y){
aint[nod].s2.insert(val);
return;
}
int mid = (st+dr)>>1;
if (x <= mid)
update (nod<<1,st,mid,x,y,val);
if (y > mid)
update ((nod<<1)|1,mid+1,dr,x,y,val);
}
void query (int nod, int st, int dr, int x, int y, int Left, int Right){
if (ok)
return;
/// query in setul2, pt ca stiu ca setul asta se afla in nodurile din tot subarborele
set<int> :: iterator it = aint[nod].s2.lower_bound(Left);
if (it != aint[nod].s2.end() && *it <= Right)
ok = 1;
if (x <= st && dr <= y){
/// acum ma intereseaza doar sa fie undeva in subarbore
it = aint[nod].s1.lower_bound(Left);
if (it != aint[nod].s1.end() && *it <= Right)
ok = 1;
return;
}
int mid = (st+dr)>>1;
if (x <= mid)
query (nod<<1,st,mid,x,y,Left,Right);
if (y > mid)
query ((nod<<1)|1,mid+1,dr,x,y,Left,Right);
}
int main (){
InParser cin ("gossips.in");
ofstream cout ("gossips.out");
cin>>n>>m>>q;
for (i=1;i<=m;++i){
cin>>x>>y;
L[x].push_back(y);
g[y]++;
}
for (i=1;i<=n;++i)
if (!g[i])
dfs (i);
for (;q--;){
cin>>tip>>x>>y;
if (tip == 1){
ok = 0;
query (1,1,n,first[x],last[x],first[y],last[y]);
if (ok)
cout<<"YES\n";
else cout<<"NO\n";
} else {
update (1,1,n,first[x],last[x],first[y]);
}
}
return 0;
}