unittest
{
	assert( [ "2 3 3", "2 2", "1 1", "1 3" ].solve == 3 );
	assert( [ "3 3 4", "3 3", "3 1", "1 1", "1 2" ].solve == 3 );
	assert( [ "5 5 10", "2 5", "4 3", "2 3", "5 5", "2 2", "5 4", "5 3", "5 1", "3 5", "1 4" ].solve == 6 );
}



import std.algorithm;
import std.conv;
import std.format;
import std.range;
import std.stdio;

void main()
{
	stdin.byLineCopy.solve.writeln;
}

auto solve( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto h = 0L;
	auto w = 0L;
	auto m = 0L;
	input.front.formattedRead!"%s %s %s"( h, w, m );
	auto hws = new long[ 2 ][ m ];
	foreach( ref hw; hws )
	{
		input.popFront;
		hw = input.front.split.to!( long[] );
		hw[] -= 1;
	}
	
	// 行ごと、列ごとの爆破対象の合計と最大数を取る
	auto pss = new bool[][]( h, w );
	auto hts = new long[ h ];
	auto wts = new long[ w ];
	auto hm = 0L;
	auto wm = 0L;
	foreach( hw; hws )
	{
		pss[ hw[ 0 ] ][ hw[ 1 ] ] = true;
		hts[ hw[ 0 ] ]++;
		wts[ hw[ 1 ] ]++;
		hm = max( hm, hts[ hw[ 0 ] ] );
		wm = max( wm, wts[ hw[ 1 ] ] );
	}
	
	// 爆破対象数が最大の行と列を抽出
	long[] ys;
	foreach( y, ht; hts )
	{
		if( ht == hm ) ys ~= y;
	}
	long[] xs;
	foreach( x, wt; wts )
	{
		if( wt == wm ) xs ~= x;
	}
	
	// 爆破対象数の最大を判定
	foreach( y; ys )
	{
		foreach( x; xs )
		{
			if( !pss[ y ][ x ] ) return wm + hm;		// 爆破対象数は最大3*10^^5なので二重ループでもTLEしない
		}
	}
	return wm + hm - 1;		// 二重カウント分を除外
}
