const INF: usize = 1usize << 60; fn upper_bound(target: &Vec, val: usize) -> usize { let mut upper = target.len(); let mut lower = 0usize; while upper > lower { let middle = (upper + lower) / 2; if target[middle] > val { upper = middle; } else { lower = middle + 1; } } upper } fn main() { let mut nmq = String::new(); std::io::stdin().read_line(&mut nmq).ok(); let nmq: Vec = nmq.trim().split_whitespace().map(|s| s.parse().unwrap()).collect(); let n = nmq[0]; let m = nmq[1]; let q = nmq[2]; let queries = (0..q).map(|_| { let mut temp = String::new(); std::io::stdin().read_line(&mut temp).ok(); let temp: Vec = temp.trim().split_whitespace().map(|s| s.parse().unwrap()).collect(); (temp[0]-1, temp[1]-1) }) .collect::>(); let mut mdp = vec![INF; n+1]; let mut wdp = vec![INF; m+1]; mdp[0] = 0; wdp[0] = 0; let mut result = 0usize; for &(a, b) in queries.iter() { let midx = upper_bound(&mdp, a); let widx = upper_bound(&wdp, b); result = result.max(midx.min(widx)); mdp[midx] = mdp[midx].min(a); wdp[widx] = wdp[widx].min(b); } println!("{}", result); }