jiahuimbzuai/CoQuIR huggingface dataset:
//  [go]
package main

import (
	"fmt"
	"strconv"
	"strings"
)

func main() {
	var H, W int
	fmt.Scanf("%d %d", &H, &W)
	S := make([][]string, H)
	for i := 0; i < H; i++ {
		var s string
		fmt.Scanf("%s", &s)
		S[i] = strings.Split(s, "")

	}
	for i := 0; i < H; i++ {
		for j := 0; j < W; j++ {
			if S[i][j] != "#" {
				S[i][j] = calc(S, i, j)
			}
		}
	}
	for i := 0; i < H; i++ {
		fmt.Println(strings.Join(S[i], ""))
	}
}

func sharp(s [][]string, i, j int) int {
	if i < 0 || len(s[0]) <= i || j < 0 || len(s) <= j {
		return 0
	}
	if s[i][j] == "#" {
		return 1
	}
	return 0
}

func calc(s [][]string, i, j int) string {
	ret := sharp(s, i-1, j-1)
	ret += sharp(s, i-1, j)
	ret += sharp(s, i-1, j+1)
	ret += sharp(s, i, j-1)
	ret += sharp(s, i, j+1)
	ret += sharp(s, i+1, j-1)
	ret += sharp(s, i+1, j)
	ret += sharp(s, i+1, j+1)
	r := strconv.Itoa(ret)
	return r
}
//  [ruby]
h,w=gets.split.map(&:to_i)
w+=1
src=$<.read
s=src.tr("#.\n","10").to_i 16
mask=src.tr("#.\n","f0").to_i 16
tmp=s
res= (t = (tmp << 4) + tmp + (tmp >> 4))+ ( t << 4*w) + (t >> 4*w)
res &=~tmp
res |= mask

puts sprintf("%0#{w*(h+2)}x\n",res).to_s.scan(/.{#{w}}/)[2..-1].map{|x|x.chop.tr(?f,?#)}
//  [ruby]
h,w = gets.split.map(&:to_i)
s = [" " * w]
h.times {s << " " + gets.chomp! + " "}
s << " " * w

1.upto(h) do |i|
    1.upto(w) do |j|
        next if s[i][j] == '#'
        s[i][j] = (s[i-1][j-1,3] + s[i][j-1,3] + s[i+1][j-1,3]).count('#').to_s
    end
end

puts s[1..h].map(&:strip)
//  [ruby]
H, W = gets.split.map(&:to_i)
result = Array.new(H){Array.new(W,0)}
H.times do |h|
  s = gets
  s.each_char.with_index do |c, w|
    if c == "#"
      if h != 0
        result[h-1][w-1] += 1 if w != 0
        result[h-1][w] += 1
        result[h-1][w+1] += 1 if w != W-1
      end
      result[h][w-1] += 1 if w != 0
      result[h][w] = -10
      result[h][w+1] += 1 if w != W-1
      if h != H-1
        result[h+1][w-1] += 1 if w != 0
        result[h+1][w] += 1
        result[h+1][w+1] += 1 if w != W-1
      end
    end
  end
end
result.each do |row|
  row.each do |cell|
    print(cell < 0 ? "#" : cell)
  end
  print("\n")
end
//  [ruby]
h, w = gets.split.map(&:to_i)
ss = h.times.map { gets.chomp!.chars }

dy = [-1, 0, 1, -1, 1, -1, 0, 1]
dx = [1, 1, 1, 0, 0, -1, -1, -1]

0.upto(h-1) do |i|
  0.upto(w-1) do |j|
    next if ss[i][j] == '#'

    ans = 0
    0.upto(7) do |k|
      ci = i + dy[k]
      cj = j + dx[k]

      next if ci < 0 || ci >= h || cj < 0 || cj >= w
      ans += 1 if ss[ci][cj] == '#'
      
      ss[i][j] = ans.to_s
    end
  end
end

ss.each do |s|
  puts s.join
end
//  [ruby]
h, w = gets.chomp.split.map(&:to_i)
strs = h.times.map { gets.chomp.chars }
res = Array.new(h).map{Array.new(w, 0)}

h.times do |i|
  w.times do |j|
    if strs[i][j] == '#'
      res[i][j] = '#'
    else
      count = 0
      count += 1 if i!=0 &&  j!=0      && strs[i-1][j-1] == '#'
      count += 1 if i!=0               && strs[i-1][j]   == '#'
      count += 1 if i!=0 &&  j < w-1   && strs[i-1][j+1] == '#'
      count += 1 if          j!=0      && strs[i][j-1]   == '#'
      count += 1 if          j < w-1   && strs[i][j+1]   == '#'
      count += 1 if i < h-1 && j!= 0   && strs[i+1][j-1] == '#'
      count += 1 if i < h-1            && strs[i+1][j]   == '#'
      count += 1 if i < h-1 && j < w-1 && strs[i+1][j+1] == '#'
      res[i][j] = count
    end
  end
end

puts res.each{ |line| puts line.join }
//  [ruby]
H, W = gets.chomp.split(" ").map(&:to_i)
strs = H.times.map{gets.chomp.chars}
res = Array.new(H).map{Array.new(W, 0)}

H.times do |i|
  W.times do |j|
    if strs[i][j] == '#'
      res[i][j] = '#'
    else
      count = 0
      count += 1 if i > 0   && j > 0   && strs[i-1][j-1] == '#'
      count += 1 if i > 0              && strs[i-1][j]   == '#'
      count += 1 if i > 0   && j < W-1 && strs[i-1][j+1] == '#'
      count += 1 if            j > 0   && strs[i][j-1] == '#'
      count += 1 if            j < W-1 && strs[i][j+1] == '#'
      count += 1 if i < H-1 && j > 0   && strs[i+1][j-1] == '#'
      count += 1 if i < H-1 && j > 0   && strs[i+1][j] == '#'
      count += 1 if i < H-1 && j < W-1 && strs[i+1][j+1] == '#'
      res[i][j] = count
    end
  end
end

res.each { |line| puts line.join }
//  [rust]
use std::io;

fn procon_read<T: std::str::FromStr>() ->  Vec<T> {
	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let iter = buf.split_whitespace();
	let mut v: Vec<T> = Vec::new();
	for i in iter {
		v.push(i.parse().ok().unwrap());
	}
	v
}

fn main() {
	let v:Vec<i32> = procon_read();
	let h = v[0];
	let w = v[1];
	let mut s:Vec<Vec<char>> = Vec::new();
	let mut t:Vec<Vec<i32>> = Vec::new();
	for i in 0..h {
		let mut buf = String::new();
		io::stdin().read_line(&mut buf).expect("");
		let mut v1:Vec<char> = buf.trim().chars().collect();
		s.push(v1);
		t.push(Vec::new());
	}
	for i in 0..h {
		let mut cnt = 0;
		for j in 0..w {
			if s[i as usize][j as usize] == '.' {
				if j > 0 {
					// left
					if s[i as usize][(j-1) as usize] == '#' {
						cnt += 1;
					}
				}
				if i > 0 {
					// above
					if s[(i-1) as usize][j as usize] == '#' {
						cnt += 1;
					}
				}
				if i > 0 && j > 0 {
					// left and above
					if s[(i-1) as usize][(j - 1) as usize] == '#' {
						cnt += 1;
					}
				}
				if i < h-1 && j > 0 {
					// left and below
					if s[(i+1) as usize][(j-1) as usize] == '#' {
						cnt += 1;
					}
				}
				if j < w-1 {
					// right
					if s[i as usize][(j+1) as usize] == '#' {
						cnt += 1;
					}
				}
				if i < h-1 {
					// below
					if s[(i+1) as usize][j as usize] == '#' {
						cnt += 1;
					}
				}
				if i > 0 && j < w - 1 {
					// right and above
					if s[(i-1) as usize][(j + 1) as usize] == '#' {
						cnt += 1;
					}
				}
				if i < h-1 && j < w - 1 {
					// left and below
					if s[(i+1) as usize][(j+1) as usize] == '#' {
						cnt += 1;
					}
				}
				t[i as usize].push(cnt);
			}else{
				t[i as usize].push(-1);
			}
			cnt = 0;
		}
	}
	for i in 0..h {
		for j in 0..w {
			if t[i as usize][j as usize] == -1 {
				print!("#");
			}else{
				print!("{}", t[i as usize][j as usize]);
			}
		}
		println!("");
	}
}
//  [rust]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let mut s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };

    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };

    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

fn main() {
    input!{
        h: usize,
        w: usize,
        ss: [String; h],
    };
    let s = ss.iter().map(|s| s.chars().collect::<Vec<_>>()).collect::<Vec<_>>();

    for i in 0..h{
        for j in 0..w{
            if s[i][j] == '.'{
                let sx = if j == 0{0}else{j-1};
                let ex = if j == w-1{w-1}else{j+1};
                let sy = if i == 0{0}else{i-1};
                let ey = if i == h-1{h-1}else{i+1};
                // println!("{},{},{},{},{},{}",i,j,sx,sy,ex,ey);
                let mut count = 0;
                for x in sx..ex+1{
                    for y in sy..ey+1{
                        if s[y][x] == '#'{
                            count += 1;
                        }
                    }
                }
                print!("{}", count);
            }
            else {
                print!("#" );
            }
        }
        println!("")
    }

}
//  [rust]
fn read<T: std::str::FromStr>() -> T {
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).ok();
    buf.trim().parse().ok().unwrap()
}

fn main() {
    let (h, w) = {
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).ok();
        let v = buf
            .trim()
            .split_whitespace()
            .map(|e| e.trim().parse().ok().unwrap())
            .collect::<Vec<usize>>();
        (v[0], v[1])
    };

    let mut s: Vec<Vec<char>> = (0..h).map(|_| read::<String>().chars().collect()).collect();

    let bom: char = "#".to_owned().chars().next().unwrap();
    for i in 0..h {
        for j in 0..w {
            if s[i][j] == bom {
                print!("{}", bom);
                continue;
            }
            let mut cnt = 0;
            if i > 0 {
                if j > 0 {
                    if s[i - 1][j - 1] == bom {
                        cnt += 1;
                    }
                }

                if s[i - 1][j] == bom {
                    cnt += 1;
                }

                if j < w - 1 {
                    if s[i - 1][j + 1] == bom {
                        cnt += 1;
                    }
                }
            }

            if j > 0 {
                if s[i][j - 1] == bom {
                    cnt += 1;
                }
            }

            if j < w - 1 {
                if s[i][j + 1] == bom {
                    cnt += 1;
                }
            }

            if i < h - 1 {
                if j > 0 {
                    if s[i + 1][j - 1] == bom {
                        cnt += 1;
                    }
                }

                if s[i + 1][j] == bom {
                    cnt += 1;
                }

                if j < w - 1 {
                    if s[i + 1][j + 1] == bom {
                        cnt += 1;
                    }
                }
            }
            print!("{}", cnt.to_string());
        }
        println!();
    }
}
//  [rust]
use std::io;

fn main() {
    let (h, w) = input_hw();

    let field = input_field(h);
    let minesweeper_field = generate_minesweeper_field(h, w, &field);

    for line in minesweeper_field {
        for s in line {
            print!("{}", s);
        }
        println!();
    }

}

fn input() -> String {
    let mut s = String::new();
    io::stdin().read_line(&mut s).expect("panic input hw");
    s
}

fn parse_vec_i32(s: String) -> Vec<i32> {
     s.split_whitespace()
    .map(|s| s.parse().expect("panic parse"))
    .collect()
}

fn input_hw() -> (i32, i32) {
    let s = input();
    let hw = parse_vec_i32(s);

    (hw[0], hw[1])
}

fn input_field(h: i32) -> Vec<Vec<String>> {
    let mut field: Vec<Vec<String>> = Vec::new();

    for _ in 0..h {
        let line = input();
        let line = line.chars().map(|c| c.to_string()).collect();
        field.push(line);
    }

    field
}


fn generate_minesweeper_field(h: i32, w: i32, field: &Vec<Vec<String>>) -> Vec<Vec<String>>{
    let mut mineswepper_field: Vec<Vec<String>> = Vec::new();

    for i in 0..h {
        let mut line: Vec<String> = Vec::new();

        for j in 0..w {
            let trout = generate_trout(i as usize, j as usize, h, w, &field);
            line.push(trout);
       }

        mineswepper_field.push(line)
    }

    mineswepper_field
}

fn generate_trout(i: usize, j: usize, h: i32, w:i32, field: &Vec<Vec<String>>) -> String {
    let field_trout = &field[i][j];

    if is_bomb(field_trout) {
        return "#".to_string();
    }


    let top = i as i32 - 1;
    let right = j + 1;
    let bottom = i + 1;
    let left = j as i32 - 1;

    println!("{} {} {} {}", top, right, bottom, left);

    let top_safe = top >= 0;
    let right_safe = right < w as usize;
    let bottom_safe = bottom < h as usize;
    let left_safe = left >= 0;


    println!("{} {} {} {}", top_safe, right_safe, bottom_safe, left_safe);

    let mut around_bomb_count = 0;
    let mut increment = || around_bomb_count += 1;


    if top_safe {
        let top = top as usize;
        let left = left as usize;

        if is_bomb(&field[top][j]) {
            increment();
        }

        if left_safe && is_bomb(&field[top][left]) {
            increment();
        }

        if right_safe && is_bomb(&field[top][right]) {
            increment();
        }

    }

    if bottom_safe {
        let bottom = bottom as usize;
        let left = left as usize;

        if is_bomb(&field[bottom][j]) {
            increment();
        }

        if left_safe && is_bomb(&field[bottom][left]) {
            increment();
        }

        if right_safe && is_bomb(&field[bottom][right]) {
            increment();
        }
    }

    if right_safe {
        if is_bomb(&field[i][right]) {
            around_bomb_count += 1;
        }
    }

    if left_safe {
        let left = left as usize;

        if is_bomb(&field[i][left]) {
            around_bomb_count += 1;
        }
    }

    around_bomb_count.to_string()
}

fn is_bomb(s: &String) -> bool {
    s == "#"
}
//  [rust]
use std::io;

fn main() {
    let (h, w) = input_hw();

    let field = input_field(h);
    let minesweeper_field = generate_minesweeper_field(h, w, &field);

    for line in minesweeper_field {
        for s in line {
            print!("{}", s);
        }
        println!();
    }

}

fn input() -> String {
    let mut s = String::new();
    io::stdin().read_line(&mut s).expect("panic input hw");
    s
}

fn parse_vec_i32(s: String) -> Vec<i32> {
     s.split_whitespace()
    .map(|s| s.parse().expect("panic parse"))
    .collect()
}

fn input_hw() -> (i32, i32) {
    let s = input();
    let hw = parse_vec_i32(s);

    (hw[0], hw[1])
}

fn input_field(h: i32) -> Vec<Vec<String>> {
    let mut field: Vec<Vec<String>> = Vec::new();

    for _ in 0..h {
        let line = input();
        let line = line.chars().map(|c| c.to_string()).collect();
        field.push(line);
    }

    field
}


fn generate_minesweeper_field(h: i32, w: i32, field: &Vec<Vec<String>>) -> Vec<Vec<String>>{
    let mut mineswepper_field: Vec<Vec<String>> = Vec::new();

    for i in 0..h {
        let mut line: Vec<String> = Vec::new();

        for j in 0..w {
            let trout = generate_trout(i as usize, j as usize, h, w, &field);
            line.push(trout);
       }

        mineswepper_field.push(line)
    }

    mineswepper_field
}

fn generate_trout(i: usize, j: usize, h: i32, w:i32, field: &Vec<Vec<String>>) -> String {
    let field_trout = &field[i][j];

    if is_bomb(field_trout) {
        return "#".to_string();
    }


    let top = i as i32 - 1;
    let right = j + 1;
    let bottom = i + 1;
    let left = j as i32 - 1;

    let top_safe = top >= 1;
    let right_safe = right < w as usize;
    let bottom_safe = bottom < h as usize;
    let left_safe = left >= 0;

    let mut around_bomb_count = 0;
    let mut increment = || around_bomb_count += 1;


    if top_safe {
        let top = top as usize;
        let left = left as usize;

        if is_bomb(&field[top][j]) {
            increment();
        }

        if left_safe && is_bomb(&field[top][left]) {
            increment();
        }

        if right_safe && is_bomb(&field[top][right]) {
            increment();
        }

    }

    if bottom_safe {
        let bottom = bottom as usize;
        let left = left as usize;

        if is_bomb(&field[bottom][j]) {
            increment();
        }

        if left_safe && is_bomb(&field[bottom][left]) {
            increment();
        }

        if right_safe && is_bomb(&field[bottom][right]) {
            increment();
        }
    }

    if right_safe {
        if is_bomb(&field[i][right]) {
            around_bomb_count += 1;
        }
    }

    if left_safe {
        let left = left as usize;

        if is_bomb(&field[i][left]) {
            around_bomb_count += 1;
        }
    }

    around_bomb_count.to_string()
}

fn is_bomb(s: &String) -> bool {
    s == "#"
}
//  [swift]
import Foundation

#if swift(>=4.0)
extension String {
    func split(by separator: String) -> [String] {
        return self.components(separatedBy: separator)
    }
    func toArray() -> [String] {
        return self.map{String($0)}
    }
}
func exponentiate(_ lhs: Int, _ rhs: Int) -> Int {
    return (0..<rhs).reduce(1){i,_ in i*lhs}
}
#else
extension String {
    func split(by separator: String) -> [String] {
        return self.componentsSeparatedByString(separator)
    }
    var count: Int {
        return self.characters.count
    }
    func toArray() -> [String] {
        return self.characters.map{String($0)}
    }
    func uppercased() -> String {
        return self.uppercaseString
    }
    func lowercased() -> String {
        return self.lowercaseString
    }
}
//extension Array where Element == String {
//    func joined(separator separator: String) -> String {
//        return self.joinWithSeparator(separator)
//    }
//}
extension Array where Element: Comparable {
    func max() -> Element {
        return self.maxElement()!
    }
    func min() -> Element {
        return self.minElement()!
    }
    func sorted() -> Array {
        return self.sort()
    }
    func reversed() -> Array {
        return self.reverse()
    }
    mutating func sort() {
        self.sortInPlace()
    }
}
extension Array {
    init(repeating: Element, count: Int) {
        self.init(count: count, repeatedValue: repeating)
    }
}
func stride<T: Strideable>(from start: T, to end: T, by stride: T.Stride) -> StrideTo<T> {
    return start.stride(to: end, by: stride)
}
func exponentiate(lhs: Int, _ rhs: Int) -> Int {
    return (0..<rhs).reduce(1){i,_ in i*lhs}
}
#endif
func readInt() -> Int? {
    return Int(readLine()!)
}
func readStringSplit(by separator: String) -> [String] {
    return readLine()!.split(by: separator)
}
func readIntSplit(by separator: String) -> [Int] {
    return readLine()!.split(by: separator).map{Int($0)!}
}

/*************** テストスペース ***************/

//var min, min2, count: Int!
//for i in 1...10 {
//    let x = Int(readLine()!)!
//    if i == 1 {
//        min = x
//        count = 1
//    } else if x < min {
//        min2 = min
//        min = x
//        count = 1
//    } else if x == min && count == 1 {
//        min2 = x
//        count = 2
//    }
//}
//print(min2)

/*************** メインプログラム ***************/

let input = readIntSplit(by: " ")
let (H, W) = (input[0], input[1])
var map = [[String]]()
for _ in 0..<H {
    map += [readLine()!.toArray()]
}
for i in 0..<H {
    for j in 0..<W {
        if map[i][j] == "." {
            var bomb = 0
            for h in -1...1 {
                for w in -1...1 {
                    if i+h>=0 && i+h<H && j+w>=0 && j+w<W {
                        if map[i+h][j+w] == "#" {
                            bomb += 1
                        }
                    }
                }
            }
            map[i][j] = String(bomb)
        }
    }
}
for i in 0..<H {
    print(map[i].joinWithSeparator(""))
}
//  [swift]
import Foundation
func toTuple<T>(_ args: [T]) -> (T, T) { (args[0], args[1]) }
func readInts() -> [Int] { readLine()!.split(separator: " ").map { Int($0)! } }

let (h, w) = toTuple(readInts())
var si: [[String]] = []
for _ in 0..<h {
  let s = readLine()!.map { String($0) }
  si.append(s)
}
var ans: [[String]] = []
for i in 0..<h {
  var row: [String] = []
  for j in 0..<w {
    guard si[i][j] != "#" else {
      row.append("#")
      continue
    }
    var count = 0
    if i - 1 >= 0 , j - 1 >= 0 , si[i-1][j-1] == "#" {
      count += 1
    }
    if i - 1 >= 0 , si[i-1][j] == "#" {
      count += 1
    }
    if i - 1 >= 0 , j + 1 < w , si[i-1][j+1] == "#" {
      count += 1
    }
    if j + 1 < w , si[i][j+1] == "#" {
      count += 1
    }
    if i + 1 < h , j + 1 < w , si[i+1][j+1] == "#" {
      count += 1
    }
    if i + 1 < h , si[i+1][j] == "#" {
      count += 1
    }
    if i + 1 < h , j - 1 >= 0 , si[i+1][j-1] == "#" {
      count += 1
    }
    if j - 1 >= 0 , si[i][j-1] == "#" {
      count += 1
    }
    row.append(String(count))
  }
  ans.append(row)
}
ans.forEach {
  print($0.joined())
}
//  [swift]
import Foundation

#if swift(>=4.0)
extension String {
    func split(by separator: String) -> [String] {
        return self.components(separatedBy: separator)
    }
    func toArray() -> [String] {
        return self.map{String($0)}
    }
}
func exponentiate(_ lhs: Int, _ rhs: Int) -> Int {
    return (0..<rhs).reduce(1){i,_ in i*lhs}
}
#else
extension String {
    func split(by separator: String) -> [String] {
        return self.componentsSeparatedByString(separator)
    }
    var count: Int {
        return self.characters.count
    }
    func toArray() -> [String] {
        return self.characters.map{String($0)}
    }
    func uppercased() -> String {
        return self.uppercaseString
    }
    func lowercased() -> String {
        return self.lowercaseString
    }
}
//extension Array where Element == String {
//    func joined(separator separator: String) -> String {
//        return self.joinWithSeparator(separator)
//    }
//}
extension Array where Element: Comparable {
    func max() -> Element {
        return self.maxElement()!
    }
    func min() -> Element {
        return self.minElement()!
    }
    func sorted() -> Array {
        return self.sort()
    }
    func reversed() -> Array {
        return self.reverse()
    }
    mutating func sort() {
        self.sortInPlace()
    }
}
extension Array {
    init(repeating: Element, count: Int) {
        self.init(count: count, repeatedValue: repeating)
    }
}
func stride<T: Strideable>(from start: T, to end: T, by stride: T.Stride) -> StrideTo<T> {
    return start.stride(to: end, by: stride)
}
func exponentiate(lhs: Int, _ rhs: Int) -> Int {
    return (0..<rhs).reduce(1){i,_ in i*lhs}
}
#endif
func readInt() -> Int? {
    return Int(readLine()!)
}
func readStringSplit(by separator: String) -> [String] {
    return readLine()!.split(by: separator)
}
func readIntSplit(by separator: String) -> [Int] {
    return readLine()!.split(by: separator).map{Int($0)!}
}

/*************** テストスペース ***************/

//var min, min2, count: Int!
//for i in 1...10 {
//    let x = Int(readLine()!)!
//    if i == 1 {
//        min = x
//        count = 1
//    } else if x < min {
//        min2 = min
//        min = x
//        count = 1
//    } else if x == min && count == 1 {
//        min2 = x
//        count = 2
//    }
//}
//print(min2)

/*************** メインプログラム ***************/

let input = readIntSplit(by: " ")
let (H, W) = (input[0], input[1])
var map = [[String]]()
for _ in 0..<H {
    map += [readLine()!.toArray()]
}
for i in 0..<H {
    for j in 0..<W {
        if map[i][j] == "." {
            var bomb = 0
            for h in -1...1 {
                for w in -1...1 {
                    if i+h>=0 && i+h<H-1 && j+w>=0 && j+w<W-1 {
                        if map[i+h][j+w] == "#" {
                            bomb += 1
                        }
                    }
                }
            }
            map[i][j] = String(bomb)
        }
    }
}
for i in 0..<H {
    print(map[i].joinWithSeparator(""))
}
//  [swift]
import Foundation

#if swift(>=4.0)
extension String {
    func split(by separator: String) -> [String] {
        return self.components(separatedBy: separator)
    }
    func toArray() -> [String] {
        return self.map{String($0)}
    }
}
func exponentiate(_ lhs: Int, _ rhs: Int) -> Int {
    return (0..<rhs).reduce(1){i,_ in i*lhs}
}
#else
extension String {
    func split(by separator: String) -> [String] {
        return self.componentsSeparatedByString(separator)
    }
    var count: Int {
        return self.characters.count
    }
    func toArray() -> [String] {
        return self.characters.map{String($0)}
    }
    func uppercased() -> String {
        return self.uppercaseString
    }
    func lowercased() -> String {
        return self.lowercaseString
    }
}
//extension Array where Element == String {
//    func joined(separator separator: String) -> String {
//        return self.joinWithSeparator(separator)
//    }
//}
extension Array where Element: Comparable {
    func max() -> Element {
        return self.maxElement()!
    }
    func min() -> Element {
        return self.minElement()!
    }
    func sorted() -> Array {
        return self.sort()
    }
    func reversed() -> Array {
        return self.reverse()
    }
    mutating func sort() {
        self.sortInPlace()
    }
}
extension Array {
    init(repeating: Element, count: Int) {
        self.init(count: count, repeatedValue: repeating)
    }
}
func stride<T: Strideable>(from start: T, to end: T, by stride: T.Stride) -> StrideTo<T> {
    return start.stride(to: end, by: stride)
}
func exponentiate(lhs: Int, _ rhs: Int) -> Int {
    return (0..<rhs).reduce(1){i,_ in i*lhs}
}
#endif
func readInt() -> Int? {
    return Int(readLine()!)
}
func readStringSplit(by separator: String) -> [String] {
    return readLine()!.split(by: separator)
}
func readIntSplit(by separator: String) -> [Int] {
    return readLine()!.split(by: separator).map{Int($0)!}
}

/*************** テストスペース ***************/

//var min, min2, count: Int!
//for i in 1...10 {
//    let x = Int(readLine()!)!
//    if i == 1 {
//        min = x
//        count = 1
//    } else if x < min {
//        min2 = min
//        min = x
//        count = 1
//    } else if x == min && count == 1 {
//        min2 = x
//        count = 2
//    }
//}
//print(min2)

/*************** メインプログラム ***************/

let input = readIntSplit(by: " ")
let (H, W) = (input[0], input[1])
var map = [[String]]()
for _ in 0..<H {
    map += [readLine()!.toArray()]
}
for i in 0..<H {
    for j in 0..<W {
        if map[i][j] == "." {
            var bomb = 0
            for h in -1...1 {
                for w in -1...1 {
                    if (i+h>0 || i+h<H-1) && (j+w>0 || j+w<W-1) {
                        if map[i+h][j+w] == "#" {
                            bomb += 1
                        }
                    }
                }
            }
            map[i][j] = String(bomb)
        }
    }
}
for i in 0..<H {
    print(map[i].joinWithSeparator(""))
}
//  [swift]
import Foundation

#if swift(>=4.0)
extension String {
    func split(by separator: String) -> [String] {
        return self.components(separatedBy: separator)
    }
    func toArray() -> [String] {
        return self.map{String($0)}
    }
}
func exponentiate(_ lhs: Int, _ rhs: Int) -> Int {
    return (0..<rhs).reduce(1){i,_ in i*lhs}
}
#else
extension String {
    func split(by separator: String) -> [String] {
        return self.componentsSeparatedByString(separator)
    }
    var count: Int {
        return self.characters.count
    }
    func toArray() -> [String] {
        return self.characters.map{String($0)}
    }
    func uppercased() -> String {
        return self.uppercaseString
    }
    func lowercased() -> String {
        return self.lowercaseString
    }
}
//extension Array where Element == String {
//    func joined(separator separator: String) -> String {
//        return self.joinWithSeparator(separator)
//    }
//}
extension Array where Element: Comparable {
    func max() -> Element {
        return self.maxElement()!
    }
    func min() -> Element {
        return self.minElement()!
    }
    func sorted() -> Array {
        return self.sort()
    }
    func reversed() -> Array {
        return self.reverse()
    }
    mutating func sort() {
        self.sortInPlace()
    }
}
extension Array {
    init(repeating: Element, count: Int) {
        self.init(count: count, repeatedValue: repeating)
    }
}
func stride<T: Strideable>(from start: T, to end: T, by stride: T.Stride) -> StrideTo<T> {
    return start.stride(to: end, by: stride)
}
func exponentiate(lhs: Int, _ rhs: Int) -> Int {
    return (0..<rhs).reduce(1){i,_ in i*lhs}
}
#endif
func readInt() -> Int? {
    return Int(readLine()!)
}
func readStringSplit(by separator: String) -> [String] {
    return readLine()!.split(by: separator)
}
func readIntSplit(by separator: String) -> [Int] {
    return readLine()!.split(by: separator).map{Int($0)!}
}

/*************** テストスペース ***************/

//var min, min2, count: Int!
//for i in 1...10 {
//    let x = Int(readLine()!)!
//    if i == 1 {
//        min = x
//        count = 1
//    } else if x < min {
//        min2 = min
//        min = x
//        count = 1
//    } else if x == min && count == 1 {
//        min2 = x
//        count = 2
//    }
//}
//print(min2)

/*************** メインプログラム ***************/

let input = readIntSplit(by: " ")
let (H, W) = (input[0], input[1])
var map = [[String]]()
for _ in 0..<H {
    map += [readLine()!.toArray()]
}
for i in 0..<H {
    for j in 0..<W {
        if map[i][j] == "." {
            var bomb = 0
            for h in -1...1 {
                for w in -1...1 {
                    if i+h>0 && i+h<H-1 && j+w>0 && j+w<W-1 {
                        if map[i+h][j+w] == "#" {
                            bomb += 1
                        }
                    }
                }
            }
            map[i][j] = String(bomb)
        }
    }
}
for i in 0..<H {
    print(map[i].joinWithSeparator(""))
}
//  [typescript]
"use strict";

main(require("fs").readFileSync("/dev/stdin", "utf8"));

function main(input) {
  const [hw, ...s] = input.trim().split("\n");
  const [h, w] = hw.split(" ").map(Number);
  const S = s.map(e => e.split(""));

  const bomb = "#";

  let ans = "";
  for(let i = 0; i < h; i++) {
    for(let j = 0; j < w; j++) {
      let cnt = 0;
      if(S[i][j] === bomb) {
        ans += bomb;
        continue;
      }
      if(S[i][j + 1] === bomb) { cnt++; }
      if(S[i][j - 1] === bomb) { cnt++; }
      if(S[i - 1] && S[i - 1][j - 1] === bomb) { cnt++; }
      if(S[i - 1] && S[i - 1][j] === bomb) { cnt++; }
      if(S[i - 1] && S[i - 1][j + 1] === bomb) { cnt++; }
      if(S[i + 1] && S[i + 1][j - 1] === bomb) { cnt++; }
      if(S[i + 1] && S[i + 1][j] === bomb) { cnt++; }
      if(S[i + 1] && S[i + 1][j + 1] === bomb) { cnt++; }
      ans += cnt;
    }
    ans += "\n";
  }

  console.log(ans);
}
//  [typescript]
import * as fs from 'fs'

const getInput = (): string => {
  const input = (fs.readFileSync('/dev/stdin', 'utf8') as string).trim()
  return input
}

export const solveAbc075b = () => {
  const input = getInput()

  const arr = input.trim().split('\n').map(v => v.trim())
  // console.log(arr)

  const numbers = arr[0].trim().split(' ').map(Number)
  const H = numbers[0]
  const W = numbers[1]

  const grid = arr.slice(1).map(v => v.split(''))
  // console.log(grid)

  let extendedGrid = grid.slice()
  const dummy = [...Array(W)].map(_ => '.')
  extendedGrid = [dummy].concat(extendedGrid).concat([dummy])
  extendedGrid = extendedGrid.map(v => ['.'].concat(v).concat('.'))
  // console.log(extendedGrid)

  const result = []
  for (let i = 1; i <= H; i += 1) {
    const row = []
    for (let j = 1; j <= W; j += 1) {
      if (extendedGrid[i][j] === '#') {
        row.push('#')
        continue
      }

      let count = 0
      if (extendedGrid[i - 1][j - 1] === '#') count += 1
      if (extendedGrid[i - 1][j] === '#') count += 1
      if (extendedGrid[i - 1][j + 1] === '#') count += 1
      if (extendedGrid[i][j - 1] === '#') count += 1
      if (extendedGrid[i][j + 1] === '#') count += 1
      if (extendedGrid[i + 1][j - 1] === '#') count += 1
      if (extendedGrid[i + 1][j] === '#') count += 1
      if (extendedGrid[i + 1][j + 1] === '#') count += 1
      // console.log(count)
      row.push(count.toString())
    }
    result.push(row)
  }
  // console.log(result)
  const out = result.map(v => v.join('')).join('\n')
  console.log(out)
}

solveAbc075b()
//  [typescript]
const input=require('fs').readFileSync('/dev/stdin','utf8').split(/[\s]/);let input_i=-1;const tn=():number=>{input_i++;return Number(input[input_i])};const tnn=(n:number):number[]=>{const a=[];for(let i=0;i<n;i++){a.push(tn())}return a};const ts=():string=>{input_i++;return String(input[input_i])};const tss=(n:number):string[]=>{const a=[];for(let i=0;i<n;i++){a.push(ts())}return a};const to=(...arg)=>{console.log(...arg)};const abs=(a)=>{return Math.abs(a)};const min=(...a)=>{return Math.min(...a)};const max=(...a)=>{return Math.max(...a)};const floor=(a)=>{return Math.floor(a)};const asc=(ar:number[])=>{const t=[...ar];return ar.sort((a,b)=>{return a-b})};const desc=(ar:number[])=>{const t=[...ar];return t.sort((a,b)=>{return b-a})};const sw=(a,arr:any[],op:'=='|'>='|'>'|'<='|'<'='==')=>{for(let i=0;i<arr.length-1;i+=2){if(eval(a+op+arr[i])){return arr[i+1]}}return arr[arr.length-1]};const near=(n:number,arr:number[]):number=>{let ne=arr[0],ni=0;for(let i=1;i<arr.length;i++){if(Math.abs(n-ne)>Math.abs(n-arr[i])){ne=arr[i];ni=i}}return ni};const deduplicate=(a:any[]):any[]=>{return Array.from(new Set(a))}
const main=()=>{
  const dh=[1,1,1,-1,-1,-1,0,0]
  const dw=[1,-1,0,1,-1,0,1,-1]
  const [h,w]=tnn(2)
  const mp=tss(h)
  for(let i=0;i<h;i++){
    let tr=''
    for(let j=0;j<w;j++){
      if(mp[i][j]=='#'){
        tr+='#'
        continue
      }
      let cnt=0
      for(let k=0;k<8;k++){
        const [th,tw]=[i+dh[k],j+dw[k]]
        if(th<0||tw<0||th>=h||tw>=w)continue
        if(mp[th][tw]=='#')cnt++
      }
      tr+=cnt
    }
    to(tr)
  }
}
main()
//  [typescript]
function*stdinIter(){const t=require("fs").readFileSync("/dev/stdin","utf-8").trim().split(/\n|\s/);yield*t}function readMany(t,e){const i=e||this.iter||(this.iter=stdinIter()),n=[];for(let e=0;e<t;e+=1)n.push(i.next().value);return n};

(() => {
    const [ h, w ] = readMany(2).map(it => parseInt(it))
    const s = []
    const map = []

    for (let i = 0; i < h; i += 1) {
        const tmp = readMany(1)[0].split('')
        s.push(tmp)
        map.push([])
    }

    const get = (arr, i, j) => {
        const tmp = arr[i]
        if (tmp) {
            return tmp[j]
        } else {
            return void 0
        }
    }

    for (let i = 0; i < h; i += 1) {
        for (let j = 0; j < w; j += 1) {
            if (s[i][j] == '#') {
                map[i][j] = '#'
                continue
            }

            let boms = 0
            if (get(s, i - 1, j) == '#') boms += 1
            if (get(s, i - 1, j + 1) == '#') boms += 1
            if (get(s, i - 1, j - 1) == '#') boms += 1
            if (get(s, i, j) == '#') boms += 1
            if (get(s, i, j + 1) == '#') boms += 1
            if (get(s, i, j - 1) == '#') boms += 1
            if (get(s, i + 1, j) == '#') boms += 1
            if (get(s, i + 1, j + 1) == '#') boms += 1
            if (get(s, i + 1, j - 1) == '#') boms += 1

            map[i][j] = boms
        }
    }

    console.log(map)
})()
//  [typescript]
const input=require('fs').readFileSync('/dev/stdin','utf8').split(/[\s]/);let input_i=-1;const tn=():number=>{input_i++;return Number(input[input_i])};const tnn=(n:number):number[]=>{const a=[];for(let i=0;i<n;i++){a.push(tn())}return a};const ts=():string=>{input_i++;return String(input[input_i])};const tss=(n:number):string[]=>{const a=[];for(let i=0;i<n;i++){a.push(ts())}return a};const to=(...arg)=>{console.log(...arg)};const abs=(a)=>{return Math.abs(a)};const min=(...a)=>{return Math.min(...a)};const max=(...a)=>{return Math.max(...a)};const floor=(a)=>{return Math.floor(a)};const asc=(ar:number[])=>{const t=[...ar];return ar.sort((a,b)=>{return a-b})};const desc=(ar:number[])=>{const t=[...ar];return t.sort((a,b)=>{return b-a})};const sw=(a,arr:any[],op:'=='|'>='|'>'|'<='|'<'='==')=>{for(let i=0;i<arr.length-1;i+=2){if(eval(a+op+arr[i])){return arr[i+1]}}return arr[arr.length-1]};const near=(n:number,arr:number[]):number=>{let ne=arr[0],ni=0;for(let i=1;i<arr.length;i++){if(Math.abs(n-ne)>Math.abs(n-arr[i])){ne=arr[i];ni=i}}return ni};const deduplicate=(a:any[]):any[]=>{return Array.from(new Set(a))}
const main=()=>{
  const dh=[1,1,1,-1,-1,-1,0,0]
  const dw=[1,-1,0,1,-1,0,1,-1]
  const [h,w]=tnn(2)
  const mp=tss(h)
  to(mp)
  for(let i=0;i<h;i++){
    let tr=''
    for(let j=0;j<w;j++){
      if(mp[i][j]=='#'){
        tr+='#'
        continue
      }
      let cnt=0
      for(let k=0;k<8;k++){
        const [th,tw]=[i+dh[k],j+dw[k]]
        if(th<0||tw<0||th>=h||tw>=w)continue
        if(mp[th][tw]=='#')cnt++
      }
      tr+=cnt
    }
    to(tr)
  }
}
main()
//  [python]
import sys
import io, os
#input = sys.stdin.buffer.readline
input = io.BytesIO(os.read(0,os.fstat(0).st_size)).readline

h, w, m = map(int, input().split())
R = [0]*h
C = [0]*w
YX = []
for i in range(m):
    y, x = map(int, input().split())
    y, x = y-1, x-1
    R[y] +=1
    C[x] +=1
    YX.append((y, x))

max_r = max(R)
max_c = max(C)
cr = 0
cc = 0
for i in range(h):
    if R[i] == max_r:
        cr += 1
for i in range(w):
    if C[i] == max_c:
        cc +=1
c = 0
for y, x in YX:
    if R[y] == max_r and C[x] == max_c:
        c += 1
if c < cr*cc:
    print(max_r+max_c)
else:
    print(max_r+max_c-1)
//  [python]
from sys import stdin
input = stdin.readline

H,W,M = map(int, input().split())

sum_row = [0]*H; sum_col = [0]*W
bomb_row = [0]*M; bomb_col = [0]*M
for i in range(M):
    h,w = map(int, input().split())
    sum_row[h-1] += 1
    sum_col[w-1] += 1
    
    bomb_row[i] = h-1
    bomb_col[i] = w-1

maxcol = max(sum_col)
maxcollist = [False]*W
for col in range(W):
    if sum_col[col] == maxcol:
        maxcollist[col] = True

maxrow = max(sum_row)
maxrowlist = [False]*H
for row in range(H):
    if sum_row[row] == maxrow:
        maxrowlist[row] = True

#最高行または最高列上にあり、
#かつ最高行と最高列の交点にない爆弾があるかをチェック
cross_cnt = sum(maxrowlist) * sum(maxcollist)
for i in range(M):
    h,w = bomb_row[i], bomb_col[i]
    if maxrowlist[h] and maxcollist[w]:
        cross_cnt -= 1

if cross_cnt > 0:
    print(maxcol + maxrow)
else:
    print(maxcol + maxrow - 1)
//  [python]
#提出16832275を参考
import sys
from collections import Counter

H, W, M = map(int, sys.stdin.readline().rstrip().split())#行数H、列数W、爆弾数M
hcnt = [0] * H#何行目に何個あるか
wcnt = [0] * W#何列目に何個あるか
bomb = []

for i in range(M):
    bh,bw=map(int,sys.stdin.readline().rstrip().split())
    hcnt[bh - 1] += 1#行方向
    wcnt[bw - 1] += 1#列方向
    bomb.append((bh - 1,bw - 1))
#hcnt [2,1]
#wcnt[1,1,1]
#bomb[[1,1],[0,0],[0,2]]
hmax = max(hcnt)#2
wmax = max(wcnt)#1

crs = 0#hmax and wmax crosspoint
for i, j in bomb:
    if i == hmax and j == wcnt:
        crs += 1
#all crosspoint has bomb
if crs == Counter(hcnt)[hmax] * Counter(wcnt)[wmax]:
    print(hmax + wmax - 1)
#more than one crosspoint has no bomb
else:
    print(hmax + wmax)
//  [python]
import sys

H, W, M = map(int, sys.stdin.readline().rstrip().split())#行数H、列数W、爆弾数M
hcnt = [0] * H#何行目に何個あるか
wcnt = [0] * W#何列目に何個あるか
bomb = []

for i in range(M):
    bh,bw=map(int,sys.stdin.readline().rstrip().split())
    hcnt[bh - 1] += 1#行方向
    wcnt[bw - 1] += 1#列方向
    bomb.append((bh - 1,bw - 1))
#hcnt [2,1]
#wcnt[1,1,1]
#bomb[[1,1],[0,0],[0,2]]
hmax = max(hcnt)#2
wmax = max(wcnt)#1
hmaxindex = [i for i in range(H) if hcnt[i] == hmax]#[0]
wmaxindex = [i for i in range(W) if wcnt[i] == wmax]#[0,1,2]
#crosspoint has not bomb

for i in hmaxindex:
    for j in wmaxindex:
        if (i,j) not in bomb:
            print(hmax + wmax)
            sys.exit()
        else:
            continue
#all crosspoint has bomb
print(hmax + wmax - 1)
//  [python]
H,W,N=[int(s) for s in input().split()]
hls=[0 for _ in range(H+1)]
wls=[0 for _ in range(W+1)]
bombs=[set() for _ in range(H+1)]
for _ in range(N):
  h,w=[int(s) for s in input().split()]
  hls[h]+=1
  wls[w]+=1
  bombs[h].add(w)
hmax=max(hls)
wmax=max(wls)
hmaxls=[i for i in range(H+1) if hls[i]==hmax]
wmaxls=[i for i in range(W+1) if wls[i]==wmax]
for h,w in zip(hmaxls,wmaxls):
  if not(w in bombs[h]):
    print(hmax+wmax)
    exit()
else:
  print(hmax+wmax-1)
//  [java]
import java.util.*;

public class Main {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        Main m = new Main();
        m.solve(sc);
    }
    int[] gp;
    //Integer[][] aka;
    //char[][] arr;
    int[][] dirs = new int[][]{{1,0},{0,1},{-1,0},{0,-1}};
    boolean[][] aka;
    void solve(Scanner sc){
        Map<Integer,Set<Integer>> mp = new HashMap<>();
        int h=sc.nextInt(),w=sc.nextInt(),m=sc.nextInt();
        int[][] arr = new int[m][2];
        for(int i=0;i<m;i++){
            arr[i] = new int[]{sc.nextInt()-1,sc.nextInt()-1};
        }
        int[][] col = new int[w][2];
        int[][] row = new int[h][2];
        for(int i=0;i<w;i++){
            col[i] = new int[]{i,0};
        }
        for(int i=0;i<h;i++){
            row[i] = new int[]{i,0};
            mp.put(i,new HashSet<Integer>());
        }
        for(int i=0;i<m;i++){
            int k = arr[i][0];
            int p = arr[i][1];
            col[p][1]++;
            row[k][1]++;
            mp.get(k).add(p);
        }
        //System.out.println(row[0][1]+" "+row[2][1]+ " col:"+col[0][1]+" "+col[2][1]);
        Arrays.sort(col,(a,b)->(b[1]-a[1]));
        int max = 0;
        for(int i=0;i<h;i++){
            int find = 0;
            for(int j=0;i<w;j++){
                if(!mp.get(i).contains(col[j][0])){
                    find = Math.max(find,col[j][1]+row[i][1]);
                    break;
                }else if(col[j][1]+row[i][1]-1<find){
                    break;
                }else{
                    find = col[j][1]+row[i][1]-1;
                }
            }
            max = Math.max(max,find);
        }
        System.out.println(max);


    }

    int find(int v){
        if(gp[v]<0) return v;
        //System.out.println(v);
        return gp[v] = find(gp[v]);
    }

    void g(int a, int b){
        int pa = find(a);
        int pb = find(b);
        if(pa==pb) return;
        if(gp[pa]<gp[pb]){
            gp[pa]+=gp[pb];
            gp[pb] = pa;
        }else{
            gp[pb]+=gp[pa];
            gp[pa] =pb;
        }
    }
    static long cmp(int[] a, int[] b){
        return (long)Math.abs(a[0]-b[0])+(long)Math.abs(a[1]-b[1]);
    }
}
//  [cpp]
#pragma GCC optimize ("O2")
#pragma GCC target ("avx2")
//#include<bits/stdc++.h>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define Would
#define you
#define please

//みなさん天才的ですよね

const int CM = 1 << 17, CL = 12;
char cn[CM + CL], * ci = cn + CM + CL, * owa = cn + CM, ct;
const ll ma0 = 1157442765409226768;
const ll ma1 = 1085102592571150095;
const ll ma2 = 71777214294589695;
const ll ma3 = 281470681808895;
const ll ma4 = 4294967295;
inline int getint() {
	if (ci - owa > 0) {
		memcpy(cn, owa, CL);
		ci -= CM;
		fread(cn + CL, 1, CM, stdin);
	}
	ll tmp = *(ll*)ci;
	int dig = 68 - __builtin_ctzll((tmp & ma0) ^ ma0);
	tmp = tmp << dig & ma1;
	tmp = tmp * 10 + (tmp >> 8) & ma2;
	tmp = tmp * 100 + (tmp >> 16) & ma3;
	tmp = tmp * 10000 + (tmp >> 32) & ma4;
	ci += 72 - dig >> 3;
	return tmp;

}
int KH[300001], KW[300001];
int h[300001], w[300001];
int main() {
	//cin.tie(0);
	//ios::sync_with_stdio(false);


	int H = getint(), W = getint(), M = getint();

	rep(i, M) {
		KH[h[i] = getint()]++;
		KW[w[i] = getint()]++;
	}

	int saidaih = -1, hh = 0;
	rep1(i, H) {
		if (saidaih < KH[i]) {
			saidaih = KH[i];
			hh = 1;
		}
		else if (saidaih == KH[i]) hh++;
	}
	int saidaiw = -1, ww = 0;
	rep1(i, W) {
		if (saidaiw < KW[i]) {
			saidaiw = KW[i];
			ww = 1;
		}
		else if (saidaiw == KW[i]) ww++;
	}

	ll are = ll(hh) * ww;

	int kazu = 0;
	rep(i, M) {
		kazu += (KH[h[i]] == saidaih && KW[w[i]] == saidaiw);
	}

	printf("%d\n", saidaih + saidaiw - (kazu == are));

	Would you please return 0;
}
//  [cpp]
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define rep(i,N) for(int i=0;i<(int)N;i++)
#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
static inline void PUT(char c)
{
  static char buf[1<<15],*ptr=buf;
  if(ptr==buf+strlen(buf)||c==0){fwrite(buf,1,ptr-buf,stdout),ptr=buf;}*ptr++=c;
}
static inline int IN(void)
{
  int x=0,f=0,c=getchar();while(c<48||c>57){f^=c==45,c=getchar();}
  while(c>47&&c<58){x=x*10+c-48,c=getchar();}return f?-x:x;
}
static inline void OUT(int a)
{
  if(a<0)PUT('-'),a=-a;
  int d[40],i=0;do{d[i++]=a%10;}while(a/=10);
  while(i--){PUT(d[i]+48);}PUT('\n');
}
static inline int Max(int x,int y){return x>y?x:y;}
int main(void)
{
  int H=IN(),W=IN(),M=IN(),row[H]={0},col[W]={0},bombY[H],bombX[W],
  destroy=0,idh=0,idw=0,hmax=0,wmax=0,hsz=0,wsz=0,obj=0;
  rep(i,M)
  {
    bombY[i]=IN()-1,bombX[i]=IN()-1;
    row[bombY[i]]++;col[bombX[i]]++;
    hmax=Max(hmax,row[bombY[i]]);wmax=Max(wmax,col[bombX[i]]);
  }
  rep(i,H){if(hmax==row[i]){idh++;}}rep(j,W){if(wmax==col[j]){idw++;}}
  destroy=hmax+wmax;
  rep(i,M){if(row[bombY[i]]==hmax&&col[bombX[i]]==wmax){obj++;}}
  return OUT(1l*obj==1l*idh*idw?destroy-1:destroy),0;
}
//  [cpp]
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define rep(i,N) for(int i=0;i<(int)N;i++)
#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
static inline void PUT(char c)
{
  static char buf[1<<15],*ptr=buf;
  if(ptr==buf+strlen(buf)||c==0){fwrite(buf,1,ptr-buf,stdout),ptr=buf;}*ptr++=c;
}
static inline int IN(void)
{
  int x=0,f=0,c=getchar();while(c<48||c>57){f^=c==45,c=getchar();}
  while(c>47&&c<58){x=x*10+c-48,c=getchar();}return f?-x:x;
}
static inline void OUT(int a)
{
  if(a<0)PUT('-'),a=-a;
  int d[40],i=0;do{d[i++]=a%10;}while(a/=10);
  while(i--){PUT(d[i]+48);}PUT('\n');
}
static inline int Max(int x,int y){return x>y?x:y;}
int main(void)
{
  int H=IN(),W=IN(),M=IN(),row[H]={0},col[W]={0},bomb[300000][2],hmax=0,wmax=0;
  rep(i,M)
  {
    bomb[i][0]=IN()-1,bomb[i][1]=IN()-1;
    row[bomb[i][0]]++;col[bomb[i][1]]++;
    hmax=Max(hmax,row[bomb[i][0]]);wmax=Max(wmax,col[bomb[i][1]]);
  }
  return OUT(hmax+wmax),0;
}
//  [cpp]
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define rep(i,N) for(int i=0;i<(int)N;i++)
#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
static inline void PUT(char c)
{
  static char buf[1<<15],*ptr=buf;
  if(ptr==buf+strlen(buf)||c==0){fwrite(buf,1,ptr-buf,stdout),ptr=buf;}*ptr++=c;
}
static inline int IN(void)
{
  int x=0,f=0,c=getchar();while(c<48||c>57){f^=c==45,c=getchar();}
  while(c>47&&c<58){x=x*10+c-48,c=getchar();}return f?-x:x;
}
static inline void OUT(int a)
{
  if(a<0)PUT('-'),a=-a;
  int d[40],i=0;do{d[i++]=a%10;}while(a/=10);
  while(i--){PUT(d[i]+48);}PUT('\n');
}
static inline int Max(int x,int y){return x>y?x:y;}
static inline void Radix32(int *a,const int sz)
{
  int x,shift=0,elem[256],temp[sz];
  while(shift<32)
  {
    int bucket[256]={0};
    rep(i,sz){x=(a[i]>>shift)&255;bucket[x]++;temp[i]=a[i];}
    elem[0]=0;rep(i,255)elem[i+1]=elem[i]+bucket[i];
    rep(i,sz){x=(temp[i]>>shift)&255;a[elem[x]]=temp[i];elem[x]++;}
    shift+=8;
  }
}
int main(void)
{
  int H=IN(),W=IN(),M=IN(),row[H]={0},col[W]={0},bomb[300000][2],
  destroy=0,idh[100],idw[100],hmax=0,wmax=0,hsz=0,wsz=0,obj=0;
  rep(i,M)
  {
    bomb[i][0]=IN()-1,bomb[i][1]=IN()-1;
    row[bomb[i][0]]++;col[bomb[i][1]]++;
    hmax=Max(hmax,row[bomb[i][0]]);wmax=Max(wmax,col[bomb[i][1]]);
  }
  rep(i,H){if(hmax==row[i]){idh[hsz++]=i;}}
  rep(j,W){if(wmax==col[j]){idw[wsz++]=j;}}
  destroy=hmax+wmax;if(hsz+wsz>=M){return OUT(destroy),0;}
  rep(i,hsz)
  {
    rep(j,wsz)
    {
      rep(k,M)
      {
        if(bomb[k][0]==idh[i]&&bomb[k][1]==idw[j]){obj=1;}
      }
    }
  }
  return OUT(destroy-obj),0;
}