//匈牙利求最大匹配
//从左边每个非匹配点出发,做一遍增广,标记所有经过的点,
//左边所有未被标记的点,和右边所有被标记的点,加起来就是要构造的方案
//左边所有的非匹配点,都被标记了,
//右边所有的非匹配点,一定没有被标记
//对于每一个匹配边,左右两点要么同时被标记,要么同时不被标记
//那么左边剩下的未被标记的点,一定是匹配点
//右边所有被标记的点,都是匹配点
//不在匹配中的情况:左边的非匹配点连向右边的匹配点(被标记)
// 左边的匹配点(不被标记)连向右边的非匹配点
//
//最小点覆盖==最大匹配数
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110;
int n, m, k;
int match[N];
bool g[N][N], st[N];
bool find(int x)
{
for (int i = 0; i < m; i ++ )
if (!st[i] && g[x][i])
{
st[i] = true;
if (match[i] == -1 || find(match[i]))
{
match[i] = x;
return true;
}
}
return false;
}
int main()
{
while (cin >> n, n)
{
cin >> m >> k;
//图
memset(g, 0, sizeof g);
memset(match, -1, sizeof match);
while (k -- )
{
int t, a, b;
cin >> t >> a >> b;
if (!a || !b)
continue;
g[a][b] = true;
}
int res = 0;
//求最大匹配数量==最少点覆盖
for (int i = 0; i < n; i ++ )
{
memset(st, 0, sizeof st);
if (find(i))
res ++ ;
}
cout << res << endl;
}
return 0;
}