2 5 10
2 2
1 1
1 4
2 1
1 2
1 5
2 4
2 5
1 3
2 3
 2 2 2
1 1
2 2
 3 3 9
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
 7 5 35
5 3
3 5
1 1
2 5
6 4
7 2
5 1
3 4
6 5
7 3
4 1
2 2
4 2
2 4
4 3
3 3
6 1
1 2
4 5
1 3
2 1
5 5
7 5
7 1
6 2
1 4
1 5
3 2
4 4
5 2
2 3
6 3
7 4
5 4
3 1
 1 5 4
1 1
1 2
1 4
1 5
 1 1 1
1 1
 5 7 21
4 4
4 5
5 5
5 6
5 7
5 1
5 2
4 2
3 2
3 1
3 7
3 6
2 6
1 6
1 7
1 1
1 2
1 3
1 4
2 4
3 4
 2 1 1
1 1
 2 2 4
2 1
1 1
1 2
2 2
 3000 3000 1
2222 738
 5 7 35
1 2
2 3
5 1
5 7
4 4
5 3
3 1
2 6
4 5
2 7
4 1
2 1
2 2
1 7
5 6
3 6
4 6
1 6
1 1
3 3
3 4
4 2
2 5
5 5
3 5
2 4
1 5
1 3
4 3
5 4
1 4
3 7
4 7
3 2
5 2
 5 4 1
4 1
 3 4 12
2 3
3 2
2 2
2 1
1 2
3 1
1 4
1 3
3 3
2 4
3 4
1 1
 3 3 3
1 1
2 2
3 3

8
 1
 6
 26
 4
 0
 20
 0
 2
 1
 28
 1
 9
 3

#include <bits/stdc++.h>
using namespace std;
template <class T, size_t D>
struct vec : vector<vec<T, D - 1>> {
  template <class... Args>
  vec(size_t n = 0, Args... args)
      : vector<vec<T, D - 1>>(n, vec<T, D - 1>(args...)) {}
};
template <class T>
struct vec<T, 1> : vector<T> {
  template <class... Args>
  vec(Args... args) : vector<T>(args...) {}
};
template <class T>
inline bool Minimize(T& a, const T& b) {
  return a > b ? a = b, true : false;
}
template <class T>
inline bool Maximize(T& a, const T& b) {
  return a < b ? a = b, true : false;
}
inline int Next(int i, int n) { return i == n - 1 ? 0 : i + 1; }
inline int Prev(int i, int n) { return !i ? n - 1 : i - 1; }
mt19937 rng(static_cast<uint32_t>(
    chrono::steady_clock::now().time_since_epoch().count()));
struct DSU {
  int n_sets;
  vec<int, 1> parents, cardinalities;
  DSU(int t_n_sets)
      : n_sets(t_n_sets), parents(n_sets), cardinalities(n_sets, 1) {
    iota((parents).begin(), (parents).end(), 0);
  }
  int Parent(int i) {
    return i == parents[i] ? i : parents[i] = Parent(parents[i]);
  }
  bool SameSet(int i, int j) { return Parent(i) == Parent(j); }
  bool Unite(int i, int j) {
    i = Parent(i);
    j = Parent(j);
    if (i == j) {
      return false;
    }
    if (cardinalities[i] > cardinalities[j]) {
      swap(i, j);
    }
    --n_sets;
    parents[i] = j;
    cardinalities[j] += cardinalities[i];
    return true;
  }
};
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n_rows, n_columns, n;
  cin >> n_rows >> n_columns >> n;
  auto Index = [&](int i, int j) { return i * (n_columns << 1) + j; };
  int answer = 0;
  vec<bool, 2> reclamated(n_rows, n_columns << 1);
  DSU dsu(n_rows * (n_columns << 1));
  vec<int, 1> new_indices(n_rows * (n_columns << 1));
  while (n--) {
    int x, y;
    cin >> x >> y;
    --x;
    --y;
    vec<int, 1> vertices;
    vec<pair<int, int>, 1> edges;
    reclamated[x][y] = true;
    for (int i = -1; i <= 1; ++i) {
      for (int j = -1; j <= 1; ++j) {
        int next_x = x + i, next_y = y + j;
        if (next_y < 0) {
          next_y += n_columns << 1;
        } else if (next_y >= (n_columns << 1)) {
          next_y -= n_columns << 1;
        }
        if (next_x < 0 || next_x >= n_rows || !reclamated[next_x][next_y]) {
          continue;
        }
        vertices.emplace_back(dsu.Parent(Index(next_x, next_y)));
        edges.emplace_back(dsu.Parent(Index(x, y)),
                           dsu.Parent(Index(next_x, next_y)));
      }
    }
    reclamated[x][y + n_columns] = true;
    for (int i = -1; i <= 1; ++i) {
      for (int j = -1; j <= 1; ++j) {
        int next_x = x + i, next_y = y + n_columns + j;
        if (next_y < 0) {
          next_y += n_columns << 1;
        } else if (next_y >= (n_columns << 1)) {
          next_y -= n_columns << 1;
        }
        if (next_x < 0 || next_x >= n_rows || !reclamated[next_x][next_y]) {
          continue;
        }
        vertices.emplace_back(dsu.Parent(Index(next_x, next_y)));
        edges.emplace_back(dsu.Parent(Index(x, y + n_columns)),
                           dsu.Parent(Index(next_x, next_y)));
      }
    }
    sort((vertices).begin(), (vertices).end());
    vertices.erase(unique((vertices).begin(), (vertices).end()),
                   vertices.end());
    for (int i = 0; i < static_cast<int>((vertices).size()); ++i) {
      new_indices[vertices[i]] = i;
    }
    DSU dsu_2(static_cast<int>((vertices).size()));
    for (auto& edge : edges) {
      dsu_2.Unite(new_indices[edge.first], new_indices[edge.second]);
    }
    if (!dsu_2.SameSet(new_indices[dsu.Parent(Index(x, y))],
                       new_indices[dsu.Parent(Index(x, y + n_columns))])) {
      ++answer;
      for (auto& edge : edges) {
        dsu.Unite(edge.first, edge.second);
      }
    } else {
      reclamated[x][y] = reclamated[x][y + n_columns] = false;
    }
  }
  cout << answer << '\n';
  return 0;
}
