#include <bits/stdc++.h>
using namespace std;
namespace FastIO {
bool bEOF;
int pos, pend;
char buf[(4 * 1024 * 1024) + 64];
void _fill_buffer() {
  int rem = pend - pos;
  if (rem < 64 && !bEOF) {
    if (rem) memcpy(buf, buf + pos, rem);
    int nread = fread(buf + rem, 1, (4 * 1024 * 1024) - rem, stdin);
    if (!nread) bEOF = true;
    pos = 0;
    pend = rem + nread;
    buf[pend] = 0;
  }
}
int nextPosInt() {
  _fill_buffer();
  int res = 0;
  while (buf[pos] <= ' ' && buf[pos]) ++pos;
  while (buf[pos] > ' ') res = res * 10 + (buf[pos++] & 15);
  return res;
}
}  // namespace FastIO
const int BASE1 = 100069;
const int MOD1 = 1000000097;
const int BASE2 = 100057;
const int MOD2 = 1000000033;
struct PrefixHashes {
  static const int BASES[2];
  static const int MODS[2];
  int N;
  int** powers;
  int** phash;
  PrefixHashes(const int _N, int arr[]) : N(_N) {
    powers = new int*[2];
    phash = new int*[2];
    for (int h = 0; h < 2; ++h) {
      powers[h] = new int[N + 1];
      powers[h][0] = 1;
      for (int i = 1; i <= N; ++i)
        powers[h][i] = (powers[h][i - 1] * 1LL * BASES[h]) % MODS[h];
      phash[h] = new int[N + 1];
      for (int i = 1; i <= N; ++i)
        phash[h][i] = (phash[h][i - 1] * 1LL * BASES[h] + arr[i]) % MODS[h];
    }
  }
  int getHash(int h, int p, int q) const {
    int res =
        (phash[h][q] - phash[h][p - 1] * 1LL * powers[h][q - p + 1]) % MODS[h];
    if (res < 0) res += MODS[h];
    return res;
  }
  pair<int, int> getHashes2(int p, int q) const {
    return {getHash(0, p, q), getHash(1, p, q)};
  }
};
const int PrefixHashes::BASES[2] = {BASE1, BASE2};
const int PrefixHashes::MODS[2] = {MOD1, MOD2};
int N, M;
int A[12][100004];
int POS[12][100004];
int getLCP(const vector<PrefixHashes>& PH, int x) {
  vector<int> Sidx(M);
  for (int m = 0, _n = (M); m < _n; ++m) Sidx[m] = POS[m][x];
  int lo = 0, hi = N;
  for (int m = 0, _n = (M); m < _n; ++m) hi = min(hi, N - Sidx[m] + 1);
  int res = 0;
  while (lo <= hi) {
    int mid = lo + (hi - lo) / 2;
    bool eq = true;
    pair<int, int> hash_ref =
        PH[M - 1].getHashes2(Sidx[M - 1], Sidx[M - 1] + mid - 1);
    for (int m = 0, _n = (M - 1); m < _n; ++m) {
      pair<int, int> h = PH[m].getHashes2(Sidx[m], Sidx[m] + mid - 1);
      if (hash_ref != h) {
        eq = false;
        break;
      }
    }
    if (eq) {
      lo = mid + 1;
      res = mid;
    } else {
      hi = mid - 1;
    }
  }
  return res;
}
long long solve() {
  if (M == 1) return N * 1LL * (N + 1) / 2;
  long long res = 0;
  vector<PrefixHashes> PH;
  for (int m = 0, _n = (M); m < _n; ++m) PH.emplace_back(N, A[m]);
  for (int m = 0, _n = (M); m < _n; ++m) {
    for (int n = (1), _b = (N); n <= _b; ++n) {
      int x = A[m][n];
      POS[m][x] = n;
    }
  }
  for (int x = (1), _b = (N); x <= _b; ++x) {
    int lcp = getLCP(PH, x);
    res += lcp;
  }
  return res;
}
int main(int argc, char* argv[]) {
  N = FastIO::nextPosInt();
  M = FastIO::nextPosInt();
  for (int m = 0, _n = (M); m < _n; ++m)
    for (int n = (1), _b = (N); n <= _b; ++n) A[m][n] = FastIO::nextPosInt();
  long long res = solve();
  printf("%lld\n", res);
  return 0;
}
